docker-deployment

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Deployment Skill

Docker部署技能

Master containerizing and deploying Node.js applications with Docker for consistent, portable deployments.
掌握使用Docker对Node.js应用进行容器化和部署的方法,实现一致、可移植的部署。

Quick Start

快速开始

Dockerize Node.js app in 3 steps:
  1. Create Dockerfile - Define container image
  2. Build Image -
    docker build -t myapp .
  3. Run Container -
    docker run -p 3000:3000 myapp
3步完成Node.js应用的Docker容器化:
  1. 创建Dockerfile - 定义容器镜像
  2. 构建镜像 -
    docker build -t myapp .
  3. 运行容器 -
    docker run -p 3000:3000 myapp

Core Concepts

核心概念

Basic Dockerfile

基础Dockerfile

dockerfile
FROM node:18-alpine

WORKDIR /app

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

COPY . .

EXPOSE 3000

CMD ["node", "src/index.js"]
dockerfile
FROM node:18-alpine

WORKDIR /app

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

COPY . .

EXPOSE 3000

CMD ["node", "src/index.js"]

Multi-Stage Build (Optimized)

优化版多阶段构建

dockerfile
undefined
dockerfile
undefined

Build stage

构建阶段

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./ RUN npm ci --only=production
COPY . .
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./ RUN npm ci --only=production
COPY . .

Production stage

生产阶段

FROM node:18-alpine
WORKDIR /app
FROM node:18-alpine
WORKDIR /app

Copy from builder

从构建阶段复制文件

COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app .
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app .

Create non-root user

创建非root用户

RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s
CMD node healthcheck.js || exit 1
CMD ["node", "src/index.js"]
undefined
RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s
CMD node healthcheck.js || exit 1
CMD ["node", "src/index.js"]
undefined

Learning Path

学习路径

Beginner (1-2 weeks)

入门级(1-2周)

  • ✅ Understand Docker basics
  • ✅ Create simple Dockerfile
  • ✅ Build and run containers
  • ✅ Manage volumes and networks
  • ✅ 理解Docker基础
  • ✅ 创建简单的Dockerfile
  • ✅ 构建并运行容器
  • ✅ 管理卷和网络

Intermediate (3-4 weeks)

进阶级(3-4周)

  • ✅ Multi-stage builds
  • ✅ Docker Compose
  • ✅ Environment variables
  • ✅ Health checks
  • ✅ 多阶段构建
  • ✅ Docker Compose
  • ✅ 环境变量
  • ✅ 健康检查

Advanced (5-6 weeks)

高级(5-6周)

  • ✅ Image optimization
  • ✅ Production best practices
  • ✅ Container orchestration
  • ✅ CI/CD integration
  • ✅ 镜像优化
  • ✅ 生产环境最佳实践
  • ✅ 容器编排
  • ✅ CI/CD集成

Docker Compose

Docker Compose

yaml
undefined
yaml
undefined

docker-compose.yml

docker-compose.yml

version: '3.8'
services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=postgresql://db:5432/myapp - REDIS_URL=redis://redis:6379 depends_on: - db - redis restart: unless-stopped
db: image: postgres:15-alpine environment: - POSTGRES_USER=myapp - POSTGRES_PASSWORD=secret - POSTGRES_DB=myapp volumes: - postgres-data:/var/lib/postgresql/data
redis: image: redis:7-alpine volumes: - redis-data:/data
nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app
volumes: postgres-data: redis-data:
undefined
version: '3.8'
services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=postgresql://db:5432/myapp - REDIS_URL=redis://redis:6379 depends_on: - db - redis restart: unless-stopped
db: image: postgres:15-alpine environment: - POSTGRES_USER=myapp - POSTGRES_PASSWORD=secret - POSTGRES_DB=myapp volumes: - postgres-data:/var/lib/postgresql/data
redis: image: redis:7-alpine volumes: - redis-data:/data
nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - app
volumes: postgres-data: redis-data:
undefined

Docker Compose Commands

Docker Compose命令

bash
undefined
bash
undefined

Start services

启动服务

docker-compose up -d
docker-compose up -d

View logs

查看日志

docker-compose logs -f app
docker-compose logs -f app

Stop services

停止服务

docker-compose down
docker-compose down

Rebuild images

重新构建镜像

docker-compose up -d --build
docker-compose up -d --build

Scale services

扩容服务

docker-compose up -d --scale app=3
undefined
docker-compose up -d --scale app=3
undefined

.dockerignore

.dockerignore

node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
.vscode
*.md
tests
coverage
.github
Dockerfile
docker-compose.yml
node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
.vscode
*.md
tests
coverage
.github
Dockerfile
docker-compose.yml

Docker Commands

Docker命令

bash
undefined
bash
undefined

Build image

构建镜像

docker build -t myapp:latest .
docker build -t myapp:latest .

Run container

运行容器

docker run -d -p 3000:3000 --name myapp myapp:latest
docker run -d -p 3000:3000 --name myapp myapp:latest

View logs

查看日志

docker logs -f myapp
docker logs -f myapp

Enter container

进入容器

docker exec -it myapp sh
docker exec -it myapp sh

Stop container

停止容器

docker stop myapp
docker stop myapp

Remove container

删除容器

docker rm myapp
docker rm myapp

List images

列出镜像

docker images
docker images

Remove image

删除镜像

docker rmi myapp:latest
docker rmi myapp:latest

Prune unused resources

清理未使用的资源

docker system prune -a
undefined
docker system prune -a
undefined

Environment Variables

环境变量

dockerfile
undefined
dockerfile
undefined

In Dockerfile

在Dockerfile中

ENV NODE_ENV=production ENV PORT=3000
ENV NODE_ENV=production ENV PORT=3000

Or in docker-compose.yml

或在docker-compose.yml中

environment:
  • NODE_ENV=production
  • PORT=3000
environment:
  • NODE_ENV=production
  • PORT=3000

Or from .env file

或从.env文件中读取

env_file:
  • .env.production
undefined
env_file:
  • .env.production
undefined

Volumes for Persistence

持久化卷

yaml
services:
  app:
    volumes:
      - ./logs:/app/logs              # Bind mount
      - node_modules:/app/node_modules # Named volume

volumes:
  node_modules:
yaml
services:
  app:
    volumes:
      - ./logs:/app/logs              # 绑定挂载
      - node_modules:/app/node_modules # 命名卷

volumes:
  node_modules:

Health Checks

健康检查

dockerfile
undefined
dockerfile
undefined

In Dockerfile

在Dockerfile中

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s
CMD node healthcheck.js || exit 1

```javascript
// healthcheck.js
const http = require('http');

const options = {
  host: 'localhost',
  port: 3000,
  path: '/health',
  timeout: 2000
};

const request = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  process.exit(res.statusCode === 200 ? 0 : 1);
});

request.on('error', (err) => {
  console.log('ERROR:', err);
  process.exit(1);
});

request.end();
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s
CMD node healthcheck.js || exit 1

```javascript
// healthcheck.js
const http = require('http');

const options = {
  host: 'localhost',
  port: 3000,
  path: '/health',
  timeout: 2000
};

const request = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  process.exit(res.statusCode === 200 ? 0 : 1);
});

request.on('error', (err) => {
  console.log('ERROR:', err);
  process.exit(1);
});

request.end();

Image Optimization

镜像优化

dockerfile
undefined
dockerfile
undefined

Use Alpine (smaller base image)

使用Alpine镜像(更小的基础镜像)

FROM node:18-alpine # 180MB vs node:18 (1GB)
FROM node:18-alpine # 180MB 对比 node:18(1GB)

Multi-stage build (remove build dependencies)

多阶段构建(移除构建依赖)

Use .dockerignore (exclude unnecessary files)

使用.dockerignore(排除不必要的文件)

npm ci instead of npm install (faster, deterministic)

使用npm ci而非npm install(更快、确定性更高)

Only production dependencies

仅安装生产依赖

RUN npm ci --only=production
RUN npm ci --only=production

Combine RUN commands (fewer layers)

合并RUN命令(减少镜像层)

RUN apk add --no-cache git &&
npm ci &&
apk del git
undefined
RUN apk add --no-cache git &&
npm ci &&
apk del git
undefined

Production Best Practices

生产环境最佳实践

dockerfile
FROM node:18-alpine
dockerfile
FROM node:18-alpine

Don't run as root

不要以root用户运行

RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
WORKDIR /app
COPY --chown=nodejs:nodejs package*.json ./ RUN npm ci --only=production
COPY --chown=nodejs:nodejs . .
USER nodejs
RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001
WORKDIR /app
COPY --chown=nodejs:nodejs package*.json ./ RUN npm ci --only=production
COPY --chown=nodejs:nodejs . .
USER nodejs

Health check

健康检查

HEALTHCHECK CMD node healthcheck.js || exit 1
HEALTHCHECK CMD node healthcheck.js || exit 1

Use node instead of npm start (better signal handling)

直接使用node命令而非npm start(更好的信号处理)

CMD ["node", "src/index.js"]
undefined
CMD ["node", "src/index.js"]
undefined

Docker Hub Deployment

Docker Hub部署

bash
undefined
bash
undefined

Login

登录

docker login
docker login

Tag image

为镜像打标签

docker tag myapp:latest username/myapp:1.0.0 docker tag myapp:latest username/myapp:latest
docker tag myapp:latest username/myapp:1.0.0 docker tag myapp:latest username/myapp:latest

Push to Docker Hub

推送到Docker Hub

docker push username/myapp:1.0.0 docker push username/myapp:latest
docker push username/myapp:1.0.0 docker push username/myapp:latest

Pull from Docker Hub

从Docker Hub拉取

docker pull username/myapp:latest
undefined
docker pull username/myapp:latest
undefined

CI/CD with GitHub Actions

使用GitHub Actions实现CI/CD

yaml
name: Docker Build & Deploy

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: docker/setup-buildx-action@v2

      - uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - uses: docker/build-push-action@v4
        with:
          push: true
          tags: username/myapp:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max
yaml
name: Docker Build & Deploy

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: docker/setup-buildx-action@v2

      - uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - uses: docker/build-push-action@v4
        with:
          push: true
          tags: username/myapp:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

Common Issues & Solutions

常见问题与解决方案

Node modules caching

Node modules缓存

dockerfile
undefined
dockerfile
undefined

Cache node_modules layer

缓存node_modules层

COPY package*.json ./ RUN npm ci COPY . . # This doesn't rebuild node_modules
undefined
COPY package*.json ./ RUN npm ci COPY . . # 此步骤不会重新构建node_modules
undefined

Signal handling

信号处理

dockerfile
undefined
dockerfile
undefined

Use node directly (not npm)

直接使用node命令(而非npm)

CMD ["node", "src/index.js"]
CMD ["node", "src/index.js"]

In app: Handle SIGTERM

在应用中处理SIGTERM信号

process.on('SIGTERM', () => { server.close(() => process.exit(0)); });
undefined
process.on('SIGTERM', () => { server.close(() => process.exit(0)); });
undefined

When to Use

适用场景

Use Docker deployment when:
  • Need consistent environments (dev, staging, prod)
  • Deploying microservices
  • Want easy scaling and orchestration
  • Using cloud platforms (AWS, GCP, Azure)
  • Implementing CI/CD pipelines
在以下场景使用Docker部署:
  • 需要一致的环境(开发、 staging、生产)
  • 部署微服务
  • 想要轻松扩容和编排
  • 使用云平台(AWS、GCP、Azure)
  • 实现CI/CD流水线

Related Skills

相关技能

  • Express REST API (containerize APIs)
  • Database Integration (multi-container setup)
  • Testing & Debugging (test in containers)
  • Performance Optimization (optimize images)
  • Express REST API(容器化API)
  • 数据库集成(多容器配置)
  • 测试与调试(在容器中测试)
  • 性能优化(优化镜像)

Resources

参考资源