准备
Demo创建
要部署,我们肯定得有一个nestjs
项目,哪怕是做的一个demo
吧,这里我们就用一个默认的nestjs cli
创建的项目作为示例。输入以下命令创建项目:
shell
nest new nestjs-docker-demo
没有安装nestjs cli
的需要先安装,命令:
shell
npm i -g @nestjs/cli
尝试运行
执行以下命令运行测试环境,看看demo
是否能启动:
shell
npm run start:dev
成功启动后,访问http://localhost:4000
应该如下图(默认3000
我改了端口号)所示:
到现在,一个已经完成的demo
就已经准备好了,接下来,我们进行打包构建并部署。
打包的小坑
打包nestjs
的项目很简单,只要执行npm run build
就会通过它的脚手架帮助我们自行打包,但是这里还是要注意一点小坑。 如果创建了不需要在生产环境使用的自定义文件夹的话,请忽略!!!
例如,正常打包目录应该如下:
但如果,这时候我们在根目录创建了例如一个scripts
目录,里面存放了一些处理脚本的命令的话,那么打包之后的目录结构如下:
这将会导致一个问题,当我们执行:npm run start:prod
的时候,对应执行node dist/main
会找不到对应模块,此时我们应该修改启动命令或者在tsconfig.build.json
文件中忽略该目录!
json
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts", "scripts"]
}
Docker
Dockerfile
要使用Docker
部署项目,首先必须得给我们的nestjs
应用创造一个镜像,在项目根目录中创建Dockerfile
文件,内容如下:
yaml
FROM node:22
WORKDIR /usr/src/app
COPY . .
RUN npm --registry https://registry.npmmirror.com
RUN npm run build
RUN rm -rf src
EXPOSE 4000
CMD ["npm", "run", "start:prod"]
上面代码的意义如下:
- 基于
node
版本22
的镜像作为基础镜像,下面的操作都依赖于此; - 设置工作目录,这里是指在
Docker
中文件的目录; - 执行命令
install
命令安装依赖; - 开放我们需要监听的端口,我用的轻量级服务器测试,需要在宝塔和阿里云两个地方都开放;
- 执行命令
npm run start:prod
表示启动应用。
上面的执行命令RUN
和CMD
的区别在于RUN
是构建镜像时就执行,CMD
是启动容器时才执行。
当编写完成上述文件后,通过命令 docker build -t nestjs-api .
来测试是否可以创建镜像。
Dockerfile构建问题
构建镜像时可能遇到构建失败的情况,例如:
shell
Error: failed to solve: node:22: failed to resolve source metadata for docker.io
所以我们首先得保证:
- 你得保证已经
docker login
登录; - 你的
docker
镜像源得有效,这里分享几个镜像源:
json
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://hub.geekery.cn",
"https://dockerpull.com"
]
docker-compose.yml
依赖上面的操作,我们其实已经可以创建一个Docker
镜像并执行了,但在实际上部署时,还需要通过编写docker-compose.yml
文件来配合使用。
在根目录中,创建docker-compose.yml
文件,编写如下内容:
yaml
services:
nestjs_api:
build:
context: .
dockerfile: Dockerfile
ports:
- 4000:4000
env_file:
- .env.production
volumes:
- ./src:/usr/src/app/src
networks:
- backend
networks:
backend:
现在来解释一下上面字段的意思:
- build:指定构建的镜像源,这里就是通过上面的
Dockerfile
创建的镜像源; - ports:该服务从本地映射到
docker
中的对应端口; - environment: 需要传递到该应用的环境变量;
- volumns: 该服务从本地磁盘内容映射到
docker
中的队友文件夹; - networks: 网关为
backend
,很重要,如果有其他服务,例如mysql
服务,那么保证两者同一个网关时nestjs
时才去访问mysql
服务。
部署
完成上述步骤后,我们将我们编写的代码和docker
需要的文件都上传到服务器上面去,然后打开对应目录的终端,执行以下命令:
css
docker-compose --env-file .env.production up -d
接着,就会自动构建镜像并且开始运行nestjs
的服务。
注意环境变量的文件,这里是.env.production
文件,保证该文件有我们需要的环境变量
当启动成功后,我们可以打开浏览器或者其他工具进行Api
访问进行服务是否启动成功。