3.5 部署

我们的服务,需要稳定运行在服务器上,最好是个linux机器。这时就不能再用deno run mod.ts来启动了,因为我们断掉 SSH 连接后服务就终止了。

部署方式这里介绍2种。

pm2

pm2 是 Node.js 下的生产环境进程管理工具,就是我们常说的进程守护工具,可以用来在生产环境中进行自动重启、日志记录、错误预警等等。

因为Deno官方没有提供类似的工具,所以我们暂时可以使用pm2来管理我们的Deno程序。

全局安装pm2:

bash 复制代码
 npm install pm2 -g

执行以下命令以启动服务:

bash 复制代码
pm2 start --name deno_blog src/main.ts --interpreter='deno' --interpreter-args='run --allow-net --allow-run --allow-env --allow-write --allow-read --importmap import_map.json --unstable'

interpreterinterpreter-args这里就是Deno的命令,其实pm2还支持其它编程语言比如Python,只是支持有限罢了。

这时看到控制台打印:

systemverilog 复制代码
┌─────┬───────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id  │ name          │ namespace   │ version │ mode    │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │
├─────┼───────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0   │ deno_blog     │ default     │ N/A     │ fork    │ 27086    │ 3m     │ 0    │ online    │ 0%       │ 79.5mb   │ root     │ disabled │
└─────┴───────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘

访问http://localhost:8000来验证功能。

pm2 常用命令:

  1. pm2 start/stop: 启动/停止程序
  2. pm2 reload/restart [id|name]: 重启程序
  3. pm2 logs [id|name]: 查看日志
  4. pm2 l/list: 列出程序列表
  5. pm2 monit: 监控程序控制台打印信息

更多命令请使用 pm2 -h 查看。或者参看这篇文章《PM2使用记录》。

docker

容器化部署是近年来的趋势,一大优点是宿主机不需要关注具体服务复杂的部署环境,也就是说你的服务是Java的,你的容器就负责把jdk等依赖项都安装好,宿主机直接运行这个容器就可以了。

对于我们的服务而言,我们的容器就是依赖于Deno。如果你对docker不熟悉,可先看遍《菜鸟教程》。

docker-compose本地运行

在根目录下创建Dockerfile,内容如下:

dockerfile 复制代码
FROM denoland/deno:alpine-1.20.6

EXPOSE 8000

WORKDIR /app

# Prefer not to run as root.
RUN chown -R deno /app
RUN chmod 755 /app
USER deno

COPY . .

RUN deno cache --import-map import_map.json src/main.ts

CMD deno run --allow-net --allow-env --allow-write --allow-read --importmap import_map.json src/main.ts

其中,第一行是Deno的镜像,alpine是官方提供的包含完整运行环境的最小镜像。根据你当前使用的Deno版本更改这里的版本号。

deno cache这一句将把src/main.ts的所有依赖项都先下载。如果没有这一句,则服务运行时才下载依赖,将会严重影响服务启动速度。

新建.dockerignore,把不需要打入镜像的文件路径写进去:

arduino 复制代码
.git
.vscode
logs
*.md
public/img

新建docker-compose.yml,用它来构建和启动镜像服务:

yaml 复制代码
version: '3'
services:
  server:
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - "8001:8000"
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./config.yaml:/app/config.yaml

其中,ports前面的端口号是宿主机要使用的,后面是容器内部暴露的。

environment这里设置中国时区,这样打印出来的时间看起来就正常了。也可以选择把它直接设置到Dockerfile里,见仁见智。

volumes是映射宿主机的配置文件到容器内,这个在生产中是常见的,因为数据库地址、日志级别这些配置项通常是要修改的。如果你的配置文件中包含敏感信息,千万不要提交到git,也不要打包到镜像中。

使用docker-compose build构建镜像,构建完成后再使用docker-compose up来启动服务。到生产时使用docker-compose up -d使用服务运行在后台。

当然,真正的生产中,更多可能是使用K8S来管理运行我们的镜像,那是一个更复杂难喻的工程,这里就不说了。

服务启动之后,在浏览器里请求http://localhost:8001来验证,这时你会看到:

所有人的图片都不见了,这也是正常的,因为我们没有把public/img文件夹复制到镜像中。那么我们应该怎么做呢?

在volumes中把这个目录挂载即可:

yaml 复制代码
volumes:
  - ./config.yaml:/app/config.yaml
  - ./public/img:/app/public/img

重启服务,就能看到页面正常了。

看到这里,你应该能够意识到,生产中你要备份好你配置的volumes文件(一般还有logs目录),这也是把它们挂载出来的目的之一,不然镜像版本升级之后,这些文件就随着上个容器的销毁而丢失了。

发布镜像

如果你的镜像只是自己单机使用,上面的教程应该就够用了。

但如果你打算在云环境使用的话,就需要把你的这个镜像发布到Docker Hub,也可以发布到阿里云之类私云上。怎么发布请自行百度。

要使用这个镜像,只需要修改docker-compose.yml,注释掉build部分,换成image即可。

yaml 复制代码
 image: 你的镜像地址:版本号
 # build:
 #   context: ./
 #   dockerfile: Dockerfile

作业

怎么部署服务到公网环境、绑定域名,不在本节讲解范围,读者可自行尝试。

本来到这里,本书就该结束了。但你思考下,我们的部署环节中是否还有什么制约点,影响我们后续服务的迭代上线?

相关推荐
爱勇宝6 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
IT_陈寒11 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码12 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo12 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志13 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..13 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects13 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰13 小时前
一些基础和问题解决
后端
陈随易13 小时前
前端项目部署只要30秒
前端·后端·程序员
YIAN14 小时前
从零手写文件读取 MCP 服务:一文吃透 Model Context Protocol 全链路通信原理
前端·后端·mcp