如何使用Docker构建Node.js生产版本并完成Express应用上线部署
先给你提个代码里的显性bug:你贴的index.js根路由里写的是response.send,这个response未定义,访问根路径会直接报500错误,先改成入参里的res:
app.get('/', (req, res) => { res.send("Back-end connected"); })
前置检查:确认项目根目录有完整的package.json,把express、cors、mongoose、dotenv这些依赖都列全,scripts字段配好启动命令"start": "node index.js",本地先跑npm install && npm start确认服务能正常在5000端口启动,再做后续Docker配置。
第一步:创建Docker配置文件
所有配置文件都放在项目根目录就行。
1. 新建.dockerignore文件
作用是过滤不需要打进镜像的文件,减小镜像体积,避免兼容问题,内容如下:
node_modules npm-debug.log .env .git .gitignore
注意:必须把node_modules列进去,千万别把本地安装的依赖文件夹打进镜像——不同系统的二进制依赖不兼容,进了Linux容器会直接报错,依赖统一在镜像构建阶段在容器环境内重新安装,最稳妥。生产环境的.env配置也不要打进镜像,后面启动容器时单独传入即可。
2. 新建Dockerfile
这是构建Docker镜像的核心规则文件,生产环境选Node长期支持版的精简稳定镜像即可,内容如下:
# 基于Node 20 LTS 精简版基础镜像构建,兼容性和体积平衡 FROM node:20-slim # 设置容器内的工作目录,后续命令都在这个路径下执行 WORKDIR /app # 先复制依赖描述文件,利用Docker分层缓存,依赖没变化时不用重复安装 COPY package*.json ./ # 生产环境安装依赖,严格按照lock文件版本装,跳过开发依赖 RUN npm ci --only=production # 复制剩余项目代码到工作目录 COPY . . # 声明容器内服务监听的端口,和你Express配置的5000端口一致 EXPOSE 5000 # 容器启动时默认执行的命令,直接启动服务 CMD ["npm", "start"]
第二步:本地验证镜像可用性
先确保本地安装并启动了Docker Desktop,在项目根目录打开终端执行构建命令:
docker build -t express-backend .
构建完成后启动本地测试容器:
docker run -d -p 5000:5000 --name test-express express-backend
参数说明:
-d:让容器在后台运行-p 5000:5000:把本机的5000端口映射到容器内的5000端口--name:给容器起个易识别的名字,方便后续操作
这时候访问http://localhost:5000能看到返回Back-end connected,就说明镜像构建正常。
第三步:生产服务器上线
1. 服务器基础配置
买好云服务器后,先在服务器上安装Docker,设置开机自启(以Ubuntu/Debian系统为例):
apt update && apt install -y docker.io systemctl start docker systemctl enable docker
记得去云服务商的控制台,把服务器安全组的入方向5000端口放开,不然外部访问不到。
2. 把镜像传到服务器
两种常用方式选一个就行:
- 方式1:本地导出镜像压缩包,通过scp等方式传到服务器,服务器端执行
docker load -i express-backend.tar加载镜像 - 方式2:把项目代码传到服务器,在服务器项目根目录直接执行
docker build -t express-backend .构建镜像,适合迭代频繁的场景
3. 生产环境启动容器
启动时通过-e参数传入生产环境的环境变量(比如MongoDB连接串等原本存在.env里的配置),一定要加自动重启策略保证服务可用性:
docker run -d \ -p 5000:5000 \ --name express-prod \ --restart=always \ -e MONGODB_URI="你的生产环境MongoDB连接地址" \ -e 其他自定义环境变量=对应值 \ express-backend
--restart=always是生产环境必加参数,服务器重启、容器异常退出时Docker会自动把服务拉起来,不用人工干预。
4. 可选优化
如果有域名,可以在服务器上装Nginx做反向代理,把域名解析到服务器IP,配置HTTPS证书,用户就可以通过域名正常访问服务了。如果MongoDB也想用容器部署,单独跑一个mongo容器,把两个容器加到同一个Docker网络里互通即可,不需要把MongoDB端口暴露到公网,安全性更高。
日常运维常用命令
- 查看正在运行的容器:
docker ps - 查看服务运行日志:
docker logs express-prod - 重启服务:
docker restart express-prod - 停止服务:
docker stop express-prod - 版本更新:停掉旧容器、删除旧容器,重新构建新镜像后按启动命令跑新容器即可
内容的提问来源于stack exchange,提问作者Teja

