章
目
录
在进行NestJS应用部署时,使用Docker可以极大地提高部署效率和环境的一致性。下面,就为大家详细介绍如何使用Docker来部署NestJS应用。
一、准备工作
(一)创建Demo项目
首先,需要有一个NestJS项目作为示例。如果还没有安装nestjs cli
,可以通过以下命令进行安装:
npm i -g @nestjs/cli
安装完成后,使用下面的命令创建一个名为nestjs - docker - demo
的项目:
nest new nestjs-docker-demo
(二)尝试运行项目
项目创建完成后,执行以下命令启动测试环境,看看项目是否能够正常启动:
npm run start:dev
若项目成功启动,在浏览器中访问http://localhost:4000
(这里端口号4000是示例,若使用默认配置,通常为3000,具体可根据实际情况调整),如果能看到“Hello World!”之类的页面内容,就说明项目启动成功。至此,一个可供部署的NestJS项目示例就准备好了。
二、打包过程中的注意事项
NestJS项目的打包操作比较简单,执行npm run build
命令,项目就会借助其脚手架自动完成打包。不过,这里有个容易忽略的小问题需要注意。如果项目中创建了一些在生产环境不需要使用的自定义文件夹,在打包时可能会出现问题。
比如,正常的打包目录结构可能类似这样:
dist
├── app.controller.d.ts
├── app.controller.js
├── app.controller.js.map
├── app.module.d.ts
├── app.module.js
├── app.module.js.map
├── app.service.d.ts
├── app.service.js
├── app.service.js.map
├── main.d.ts
├── main.js
├── main.js.map
└── tsconfig.build.tsbuildinfo
node_modules
src
test
但要是在根目录创建了一个像scripts
这样存放处理脚本命令的目录,打包后的目录结构可能就会变成这样:
NESTJS-DOCKER-DEMO
├── dist
│ └── scripts
├── src
├── tsconfig.build.tsbuildinfo
├── node_modules
├── scripts
├── test.ts
├── .gitignore
├── .prettierrc
├── eslint.config.mjs
└── nest-cli.json
这种情况下,当执行npm run start:prod
(实际对应node dist/main
命令)时,就可能会出现找不到对应模块的错误。为了解决这个问题,可以修改启动命令,或者在tsconfig.build.json
文件中忽略该目录,配置如下:
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts", "scripts"]
}
三、创建Docker镜像
(一)编写Dockerfile
要使用Docker部署NestJS应用,首先要为应用创建一个镜像。在项目的根目录下创建一个名为Dockerfile
的文件,内容如下:
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"]
下面逐行解释一下这段代码的含义:
FROM node:22
:表示基于node
版本为22
的镜像作为基础镜像,后续的操作都在这个基础上进行。WORKDIR /usr/src/app
:设置在Docker容器中的工作目录,后续的文件操作等都在这个目录下执行。COPY . .
:将当前项目目录下的所有文件复制到Docker容器的工作目录中。RUN npm --registry https://registry.npmmirror.com
:通过指定的镜像源安装项目依赖。RUN npm run build
:执行项目的打包命令。RUN rm -rf src
:删除项目的源文件目录,因为打包后的文件已经包含了运行所需的内容,源文件在生产环境中可以不再保留,这样能减小镜像体积。EXPOSE 4000
:指定容器要监听的端口,这里设置为4000,实际使用时可根据项目需求调整。CMD ["npm", "run", "start:prod"]
:当容器启动时,执行npm run start:prod
命令来启动应用。这里要注意RUN
和CMD
的区别,RUN
命令是在构建镜像时执行,而CMD
命令是在启动容器时才执行。
完成Dockerfile
的编写后,可以使用docker build -t nestjs-api .
命令来测试是否能够成功创建镜像。
(二)解决Dockerfile构建问题
在构建镜像的过程中,可能会遇到构建失败的情况,例如出现Error: failed to solve: node:22: failed to resolve source metadata for docker.io
这样的错误提示。为了避免这类问题,需要确保以下两点:
- 确保已经使用
docker login
命令登录到Docker。 - 保证所使用的Docker镜像源有效。下面分享几个常用的镜像源:
"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的配置中进行设置。
四、编写docker-compose.yml文件
虽然通过前面的操作已经可以创建并运行Docker镜像,但在实际部署中,通常还需要编写docker-compose.yml
文件来进行更方便的管理和配置。
在项目根目录下创建docker-compose.yml
文件,并编写以下内容:
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
:用于指定端口映射,将本地的4000端口映射到Docker容器内的4000端口,这样外部就可以通过访问本地4000端口来访问容器内的应用服务,实际使用时可根据需要修改端口号。env_file
:指定传递给应用的环境变量文件,这里使用.env.production
文件,确保该文件包含项目运行所需的环境变量。volumes
:用于设置目录挂载,将本地的src
目录挂载到Docker容器内的/usr/src/app/src
目录,这样在本地对src
目录的修改可以实时同步到容器内,方便开发和调试。networks
:指定服务所在的网络,这里设置为backend
。如果项目中还有其他服务,比如mysql
服务,只有当它们处于同一个网络时,nestjs
应用才能访问mysql
服务。
五、部署应用
完成上述所有文件的编写和配置后,将项目代码以及相关的Docker文件上传到服务器。然后在服务器上打开项目目录对应的终端,执行以下命令:
docker-compose --env-file .env.production up -d
这条命令会自动构建镜像并启动NestJS应用服务。执行命令时要注意指定正确的环境变量文件.env.production
,确保其中包含项目运行所需的环境变量。
当服务启动成功后,就可以通过浏览器或者其他工具访问对应的API,以此来检查服务是否正常运行。
通过以上步骤,就可以成功地使用Docker部署NestJS应用了。在实际操作过程中,可能会遇到各种不同的问题,需要根据具体情况进行排查和解决。希望这篇文章能帮助大家顺利完成NestJS应用的Docker部署工作。