Node.js 编程实战:部署 Node.js 应用 —— Docker 容器化部署

随着 Node.js 应用从开发环境迁移到生产环境,传统的直接部署方式(如裸机、PM2 守护进程)虽然可行,但在环境一致性、快速部署、可扩展性 上仍存在一定局限。

Docker 容器化部署 提供了一种轻量、可移植、环境一致的解决方案,使得应用可以在任何支持 Docker 的环境中运行,且无需担心依赖冲突或环境差异。

本文将从实战角度,讲解如何将 Node.js 应用容器化,并完成从构建、运行到优化的全过程。


一、为什么选择 Docker 部署 Node.js 应用

Docker 提供了以下核心优势:

    1. 环境隔离
      每个应用运行在独立容器中,不会与系统环境或其他应用冲突。
    1. 快速部署与迁移
      一次构建的镜像可以在任何 Docker 支持的服务器上运行,部署过程几乎无需额外配置。
    1. 便于 CI/CD
      容器镜像可直接推送到镜像仓库,实现流水线自动化部署。
    1. 轻量与高效
      容器相比虚拟机占用更少资源,启动速度快。
    1. 易于扩展与负载均衡
      可配合 Docker Compose 或 Kubernetes,快速扩容多实例。

二、准备 Node.js 应用

假设我们的项目结构如下:

复制代码
my-app/
├── app.js
├── package.json
└── package-lock.json

确保应用在本地可以正常启动:

复制代码
node app.js

三、编写 Dockerfile

Dockerfile 是容器构建的核心。

  1. 基础 Dockerfile 示例

    使用官方 Node.js LTS 版本作为基础镜像

    FROM node:20-alpine

    设置工作目录

    WORKDIR /usr/src/app

    复制 package.json 和 package-lock.json

    COPY package*.json ./

    安装依赖

    RUN npm install --production

    复制应用代码

    COPY . .

    暴露容器端口

    EXPOSE 3000

    启动应用

    CMD ["node", "app.js"]

说明:

  • • node:20-alpine 是轻量级 Node.js 官方镜像
  • • WORKDIR 定义容器内工作目录
  • • npm install --production 仅安装生产依赖
  • • EXPOSE 3000 用于容器端口映射
  • • CMD 指定容器启动命令

  1. 优化 Dockerfile

    1. 缓存依赖安装

    COPY package*.json ./
    RUN npm ci --only=production

使用 npm ci 速度更快,并保证依赖一致性。

    1. 减少镜像体积

    FROM node:20-alpine AS builder

    WORKDIR /usr/src/app
    COPY package*.json ./
    RUN npm install --production
    COPY . .

    FROM node:20-alpine
    WORKDIR /usr/src/app
    COPY --from=builder /usr/src/app .
    EXPOSE 3000
    CMD ["node", "app.js"]

使用多阶段构建,仅将最终产物放入镜像,显著减小体积。


四、构建镜像

在项目根目录下执行:

复制代码
 docker build -t my-app:1.0 .
  • • my-app:1.0 是镜像名称和标签
  • • . 表示 Dockerfile 所在目录

构建完成后,可以查看镜像:

复制代码
docker images

五、运行容器

复制代码
 docker run -d -p 3000:3000 --name my-app-container my-app:1.0

说明:

  • • -d 后台运行
  • • -p 3000:3000 将容器 3000 端口映射到宿主机 3000 端口
  • • --name 指定容器名称

访问 http://localhost:3000 即可看到应用运行效果。


六、使用 Docker Compose 管理

当应用依赖数据库或缓存时,Docker Compose 可以统一管理多服务。

  1. 示例 docker-compose.yml

    version: "3.9"
    services:
    app:
    build: .
    container_name: my-app
    ports:
    - "3000:3000"
    environment:
    NODE_ENV: production
    depends_on:
    - redis
    - db

    db:
    image: mysql:8
    environment:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: mydb
    ports:
    - "3306:3306"

    redis:
    image: redis:7
    ports:
    - "6379:6379"

  2. 启动多服务

    docker-compose up -d

一条命令即可启动应用及依赖服务,并保持网络互通。


七、镜像优化与安全建议

    1. 使用 Alpine 或 Slim 镜像 减少体积
    1. 安装依赖尽量使用 --production 或 --only=prod
    1. 多阶段构建,避免将开发工具带入生产镜像
    1. 配置 非 root 用户 运行应用
    1. 定期更新基础镜像,修复安全漏洞
    1. 使用 .dockerignore 忽略不必要文件

八、日志管理

Docker 容器的日志默认输出到标准输出(stdout)和标准错误(stderr)。可以通过以下方式查看:

复制代码
docker logs -f my-app-container

结合 Docker Compose,可统一查看多服务日志:

复制代码
docker-compose logs -f

生产环境建议配合 ELK 或 Loki 做集中日志管理与分析。


九、容器更新与滚动部署

    1. 构建新镜像:

    docker build -t my-app:1.1 .

    1. 停止旧容器并删除:

    docker stop my-app-container
    docker rm my-app-container

    1. 启动新容器:

    docker run -d -p 3000:3000 --name my-app-container my-app:1.1

配合 CI/CD 可实现自动化滚动更新,减少停机时间。


十、总结

使用 Docker 容器化部署 Node.js 应用有以下优势:

  • • 环境一致性,避免依赖冲突
  • • 快速部署与迁移
  • • 多服务统一管理(Docker Compose)
  • • 易于扩展与负载均衡
  • • 集成 CI/CD 流程,实现自动化发布

在《Node.js 编程实战》系列中,Docker 部署为应用走向生产环境奠定了基础,同时也为后续 Kubernetes、高可用集群以及微服务架构提供了良好扩展性。

原文: https://juejin.cn/post/75989476

相关推荐
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
分布式存储与RustFS3 天前
MinIO 官方 Docker 镜像被移除:依赖它的项目该怎么办
docker·云原生·devops·对象存储·minio·分布式存储
玉&心3 天前
通过Arthas在线诊断K8S中的内存及JVM等使用情况
docker·k8s·arthas
xing-xing3 天前
Docker容器中Nginx站点根目录网页配置访问
nginx·docker
赵文宇(温玉)3 天前
CoreDNS的hosts插件的缺行配置导致k8s集群异常
容器·kubernetes·rancher
guo_wen_qiang3 天前
上传本地镜像到harbor中
docker·容器·持续部署
羑悻的小杀马特3 天前
Dockerfile 全景指南:从入门编写dockerfile到生产环境镜像优化实战,一步步带你从啃透制作指令到镜像制作落地!
docker·dockerfile·镜像制作
BianHuanShiZhe3 天前
docker常见命令
docker
正经教主3 天前
【FDE系列】阶段2:Day 43:Docker Compose — 多容器一键编排
人工智能·docker·fde
忆~遂愿3 天前
本地片库怎么在外面打开?Plex + cpolar 搭一套可远程访问的私人影音库
docker·容器