温馨提示×

Ubuntu Nodejs与Docker如何结合

小樊
32
2025-12-27 21:24:46
栏目: 编程语言

在 Ubuntu 上把 Node.js 应用容器化,核心流程包括:安装环境、编写 Dockerfile 与可选的 docker-compose.yml、构建镜像并运行容器,同时兼顾开发环境与生产环境的差异与优化。

一 环境准备

  • 安装 Node.js(任选其一)
    • 使用官方仓库:sudo apt update && sudo apt install -y nodejs npm
    • 使用 NodeSource 仓库(以 LTS 版本为例):导入 GPG 并添加源后安装
    • 使用 NVM:安装 nvm 后执行 nvm install 16 && nvm use 16
  • 安装 Docker(任选其一)
    • 使用官方脚本:curl -fsSL https://get.docker.com | sudo sh
    • 使用 APT 安装 docker.iosudo apt update && sudo apt install -y docker.io
    • 使用 APT 安装 docker-ce:添加 Docker GPG 与仓库后安装,并启动服务:sudo systemctl start docker && sudo systemctl enable docker
  • 验证安装
    • 查看版本:node -v、npm -v
    • 运行测试容器:docker run hello-world

二 快速上手示例

  • 示例应用
    • 创建项目:mkdir my-node-app && cd my-node-app && npm init -y
    • 安装依赖:npm install express
    • 创建入口:echo “const express=require(‘express’);const app=express();app.get(‘/’,(_,res)=>res.send(‘Hello, Docker’));app.listen(3000,()=>console.log(‘Server on 3000’));” > app.js
  • Dockerfile(生产就绪)
    • 示例:
      FROM node:18-alpine
      WORKDIR /usr/src/app
      COPY package*.json ./
      RUN npm ci --only=production
      COPY . .
      EXPOSE 3000
      USER node
      CMD ["node","app.js"]
      
    • 说明:选择 node:18-alpine 体积更小;使用 npm ci 更快更可复现;设置 USER node 提升安全性;通过 EXPOSE 3000 声明端口;CMD 指定启动命令。
  • 构建与运行
    • 构建:docker build -t my-node-app .
    • 运行:docker run -d --name my-running-app -p 3000:3000 my-node-app
    • 验证:浏览器访问 http://<服务器IP>:3000http://localhost:3000

三 开发环境最佳实践

  • 使用 Docker Compose 管理多服务(如 Node + MongoDB)
    • 示例 docker-compose.yml:
      version: "3.8"
      services:
        app:
          build: .
          ports:
            - "3000:3000"
          environment:
            - NODE_ENV=development
            - MONGO_URI=mongodb://mongo:27017/mydb
          volumes:
            - .:/usr/src/app
            - /usr/src/app/node_modules
          depends_on:
            - mongo
        mongo:
          image: mongo:6
          environment:
            MONGO_INITDB_ROOT_USERNAME: root
            MONGO_INITDB_ROOT_PASSWORD: example
          volumes:
            - mongo-data:/data/db
      volumes:
        mongo-data:
      
    • 启动:docker-compose up -d;开发时挂载代码目录实现热更新,使用独立 node_modules 卷避免被覆盖。
  • 使用 nodemon 实现代码变更自动重启
    • 安装:npm i -D nodemon
    • package.json 脚本:“dev”: “nodemon app.js”
    • 开发时在 Compose 覆盖命令:
      command: ["npm","run","dev"]
      
  • 通过 .env 管理环境变量,代码中用 process.env 读取配置,避免硬编码。

四 生产优化与常见问题

  • 多阶段构建(减小镜像体积,提升安全性)
    FROM node:18-alpine AS builder
    WORKDIR /usr/src/app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    
    FROM node:18-alpine
    WORKDIR /usr/src/app
    COPY --from=builder /usr/src/app/dist ./dist
    COPY package*.json ./
    RUN npm ci --only=production
    USER node
    CMD ["node","dist/index.js"]
    
  • 使用 .dockerignore 排除 node_modules、.git、.env 等不必要文件,减少构建上下文与层大小。
  • 非 root 运行:在 Dockerfile 中设置 USER node,并在卷挂载时避免覆盖容器内的 node_modules
  • 健康检查:在 Compose 中添加
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
    
  • 常见问题
    • 端口未开放:确保云服务器安全组/防火墙放行 3000;本地访问使用 http://localhost:3000
    • 本地模块覆盖:使用匿名卷 /usr/src/app/node_modules 隔离依赖。
    • 缓存导致依赖不一致:优先使用 npm ci,并在 package.json 锁定版本。

0