docker

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Containerization Skill

Docker容器化技能

Summary

概述

Docker provides containerization for packaging applications with their dependencies into isolated, portable units. Containers ensure consistency across development, testing, and production environments, eliminating "works on my machine" problems.
Docker提供容器化功能,可将应用及其依赖项打包为隔离、可移植的单元。容器确保开发、测试和生产环境的一致性,消除了“在我机器上能运行”的问题。

When to Use

适用场景

  • Local Development: Consistent dev environments across team members
  • CI/CD Pipelines: Reproducible build and test environments
  • Microservices: Isolated services with independent scaling
  • Production Deployment: Portable applications across cloud providers
  • Database/Service Testing: Ephemeral databases for integration tests
  • Legacy Application Isolation: Run incompatible dependencies side-by-side
  • 本地开发: 为团队成员提供一致的开发环境
  • CI/CD流水线: 可重现的构建和测试环境
  • 微服务: 可独立扩展的隔离服务
  • 生产部署: 可在各云服务商间移植的应用
  • 数据库/服务测试: 用于集成测试的临时数据库
  • 遗留应用隔离: 并行运行存在依赖冲突的应用

Quick Start

快速入门

1. Create Dockerfile

1. 创建Dockerfile

dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

2. Build Image

2. 构建镜像

bash
docker build -t myapp:1.0 .
bash
docker build -t myapp:1.0 .

3. Run Container

3. 运行容器

bash
docker run -p 3000:3000 myapp:1.0

bash
docker run -p 3000:3000 myapp:1.0

Core Concepts

核心概念

Images vs Containers

镜像 vs 容器

  • Image: Read-only template with application code, runtime, and dependencies
  • Container: Running instance of an image with writable layer
  • Registry: Storage for images (Docker Hub, GitHub Container Registry)
  • 镜像(Image): 包含应用代码、运行时和依赖项的只读模板
  • 容器(Container): 镜像的运行实例,带有可写层
  • 镜像仓库(Registry): 镜像的存储服务(如Docker Hub、GitHub Container Registry)

Layers and Caching

分层与缓存

Each Dockerfile instruction creates a layer. Docker caches unchanged layers for faster builds.
dockerfile
undefined
Dockerfile中的每条指令都会创建一个分层。Docker会缓存未更改的分层以加快构建速度。
dockerfile
undefined

GOOD: Dependencies change less frequently than code

GOOD: Dependencies change less frequently than code

FROM python:3.11-slim COPY requirements.txt . RUN pip install -r requirements.txt # Cached unless requirements.txt changes COPY . . # Rebuild only when code changes
FROM python:3.11-slim COPY requirements.txt . RUN pip install -r requirements.txt # Cached unless requirements.txt changes COPY . . # Rebuild only when code changes

BAD: Invalidates cache on every code change

BAD: Invalidates cache on every code change

FROM python:3.11-slim COPY . . # Changes frequently RUN pip install -r requirements.txt # Reinstalls on every build
undefined
FROM python:3.11-slim COPY . . # Changes frequently RUN pip install -r requirements.txt # Reinstalls on every build
undefined

Volumes

Persistent data storage that survives container restarts.
bash
undefined
可持久化存储数据,在容器重启后仍能保留。
bash
undefined

Named volume (managed by Docker)

命名卷(由Docker管理)

docker run -v mydata:/app/data myapp
docker run -v mydata:/app/data myapp

Bind mount (host directory)

绑定挂载(主机目录)

docker run -v $(pwd)/data:/app/data myapp
docker run -v $(pwd)/data:/app/data myapp

Anonymous volume (temporary)

匿名卷(临时)

docker run -v /app/data myapp
undefined
docker run -v /app/data myapp
undefined

Networks

网络

Containers communicate through Docker networks.
bash
undefined
容器通过Docker网络进行通信。
bash
undefined

Create network

创建网络

docker network create mynetwork
docker network create mynetwork

Run containers on network

在网络上运行容器

docker run --network mynetwork --name db postgres docker run --network mynetwork --name app myapp
docker run --network mynetwork --name db postgres docker run --network mynetwork --name app myapp

App can connect to db using hostname "db"

应用可通过主机名"db"连接到数据库


---

---

Dockerfile Basics

Dockerfile基础

Essential Instructions

核心指令

dockerfile
undefined
dockerfile
undefined

Base image

基础镜像

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

Metadata

元数据

LABEL maintainer="dev@example.com" LABEL version="1.0"
LABEL maintainer="dev@example.com" LABEL version="1.0"

Set working directory

设置工作目录

WORKDIR /app
WORKDIR /app

Copy files

复制文件

COPY package*.json ./ COPY src/ ./src/
COPY package*.json ./ COPY src/ ./src/

Run commands (creates layer)

运行命令(创建分层)

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

Set environment variables

设置环境变量

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

Expose ports (documentation only)

暴露端口(仅为文档说明)

EXPOSE 3000
EXPOSE 3000

Default command

默认命令

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

Alternative: ENTRYPOINT (not overridden by docker run args)

替代方案:ENTRYPOINT(不会被docker run参数覆盖)

ENTRYPOINT ["node"] CMD ["src/server.js"] # Default args for ENTRYPOINT
undefined
ENTRYPOINT ["node"] CMD ["src/server.js"] # ENTRYPOINT的默认参数
undefined

Instruction Order for Cache Efficiency

缓存优化的指令顺序

dockerfile
undefined
dockerfile
undefined

1. Base image (rarely changes)

1. 基础镜像(极少更改)

FROM python:3.11-slim
FROM python:3.11-slim

2. System dependencies (rarely change)

2. 系统依赖(极少更改)

RUN apt-get update && apt-get install -y
gcc
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
gcc
&& rm -rf /var/lib/apt/lists/*

3. Application dependencies (change occasionally)

3. 应用依赖(偶尔更改)

COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt

4. Application code (changes frequently)

4. 应用代码(频繁更改)

COPY . .
COPY . .

5. Runtime configuration

5. 运行时配置

ENV PYTHONUNBUFFERED=1 EXPOSE 8000 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
undefined
ENV PYTHONUNBUFFERED=1 EXPOSE 8000 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
undefined

.dockerignore

.dockerignore

Exclude files from build context (faster builds, smaller images).
undefined
从构建上下文排除文件(加快构建速度,减小镜像体积)。
undefined

.dockerignore

.dockerignore

node_modules/ npm-debug.log .git/ .gitignore *.md .env .vscode/ pycache/ *.pyc .pytest_cache/ coverage/ dist/ build/

---
node_modules/ npm-debug.log .git/ .gitignore *.md .env .vscode/ pycache/ *.pyc .pytest_cache/ coverage/ dist/ build/

---

Multi-Stage Builds

多阶段构建

Optimize image size by separating build and runtime stages.
通过分离构建阶段和运行时阶段来优化镜像体积。

Node.js TypeScript Example

Node.js TypeScript示例

dockerfile
undefined
dockerfile
undefined

Build stage

构建阶段

FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build

Production stage

生产阶段

FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/server.js"]

**Benefits**:
- Build dependencies (TypeScript, webpack) excluded from final image
- Final image: ~50MB vs ~500MB with build tools
- Faster deployments and reduced attack surface
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/server.js"]

**优势**:
- 最终镜像中排除构建依赖(TypeScript、webpack)
- 最终镜像体积:约50MB,相比包含构建工具的镜像缩小至十分之一
- 更快的部署速度和更小的攻击面

Python Example

Python示例

dockerfile
undefined
dockerfile
undefined

Build stage

构建阶段

FROM python:3.11 AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.11 AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user --no-cache-dir -r requirements.txt

Runtime stage

运行时阶段

FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD ["python", "app.py"]
undefined
FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD ["python", "app.py"]
undefined

Go Example (Smallest Images)

Go示例(最小镜像)

dockerfile
undefined
dockerfile
undefined

Build stage

构建阶段

FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.* ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o server
FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.* ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o server

Runtime stage (scratch = empty base image)

运行时阶段(scratch = 空基础镜像)

FROM scratch COPY --from=builder /app/server /server EXPOSE 8080 ENTRYPOINT ["/server"]

Result: ~10MB final image containing only the compiled binary.

---
FROM scratch COPY --from=builder /app/server /server EXPOSE 8080 ENTRYPOINT ["/server"]

结果:仅包含编译后二进制文件的约10MB最终镜像。

---

Docker Compose

Docker Compose

Define multi-container applications in YAML.
使用YAML定义多容器应用。

Basic Structure

基本结构

yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
    volumes:
      - ./src:/app/src  # Hot reload in development

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  db_data:
yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
    volumes:
      - ./src:/app/src  # 开发环境热重载

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  db_data:

Commands

命令

bash
undefined
bash
undefined

Start all services

启动所有服务

docker-compose up
docker-compose up

Start in background

后台启动

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

Rebuild images

重新构建镜像

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

Stop services

停止服务

docker-compose down
docker-compose down

Stop and remove volumes

停止并删除卷

docker-compose down -v
docker-compose down -v

View logs

查看日志

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

Run one-off command

运行一次性命令

docker-compose run app npm test
undefined
docker-compose run app npm test
undefined

Full Stack Example

全栈示例

yaml
version: '3.8'

services:
  # Frontend
  web:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    environment:
      - REACT_APP_API_URL=http://localhost:8000

  # Backend API
  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./backend:/app
    command: uvicorn main:app --host 0.0.0.0 --reload

  # Database
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Cache
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  # Worker (background jobs)
  worker:
    build: ./backend
    command: celery -A tasks worker --loglevel=info
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - db

volumes:
  db_data:
  redis_data:

networks:
  default:
    name: myapp_network

yaml
version: '3.8'

services:
  # 前端
  web:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    environment:
      - REACT_APP_API_URL=http://localhost:8000

  # 后端API
  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./backend:/app
    command: uvicorn main:app --host 0.0.0.0 --reload

  # 数据库
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # 缓存
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  # 工作进程(后台任务)
  worker:
    build: ./backend
    command: celery -A tasks worker --loglevel=info
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - db

volumes:
  db_data:
  redis_data:

networks:
  default:
    name: myapp_network

Development Workflows

开发工作流

Hot Reload with Volumes

卷实现热重载

Node.js

Node.js

yaml
services:
  app:
    build: .
    volumes:
      - ./src:/app/src        # Sync source code
      - /app/node_modules     # Prevent overwriting container's node_modules
    command: npm run dev
dockerfile
undefined
yaml
services:
  app:
    build: .
    volumes:
      - ./src:/app/src        # 同步源代码
      - /app/node_modules     # 防止覆盖容器的node_modules
    command: npm run dev
dockerfile
undefined

Dockerfile.dev

Dockerfile.dev

FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install # Include dev dependencies COPY . . EXPOSE 3000 CMD ["npm", "run", "dev"]
undefined
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install # 包含开发依赖 COPY . . EXPOSE 3000 CMD ["npm", "run", "dev"]
undefined

Python (Django/FastAPI)

Python (Django/FastAPI)

yaml
services:
  web:
    build: .
    volumes:
      - .:/app
    command: python manage.py runserver 0.0.0.0:8000
    # or for FastAPI:
    # command: uvicorn main:app --host 0.0.0.0 --reload
yaml
services:
  web:
    build: .
    volumes:
      - .:/app
    command: python manage.py runserver 0.0.0.0:8000
    # 或FastAPI使用:
    # command: uvicorn main:app --host 0.0.0.0 --reload

VS Code Dev Containers

VS Code开发容器

.devcontainer/devcontainer.json
:
json
{
  "name": "Python Dev Container",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/app",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "postCreateCommand": "pip install -r requirements-dev.txt",
  "remoteUser": "vscode"
}
.devcontainer/devcontainer.json
:
json
{
  "name": "Python Dev Container",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/app",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "postCreateCommand": "pip install -r requirements-dev.txt",
  "remoteUser": "vscode"
}

Local Database Containers

本地数据库容器

bash
undefined
bash
undefined

PostgreSQL

PostgreSQL

docker run -d
--name dev-postgres
-e POSTGRES_PASSWORD=localdev
-e POSTGRES_DB=myapp_dev
-p 5432:5432
-v pgdata:/var/lib/postgresql/data
postgres:15-alpine
docker run -d
--name dev-postgres
-e POSTGRES_PASSWORD=localdev
-e POSTGRES_DB=myapp_dev
-p 5432:5432
-v pgdata:/var/lib/postgresql/data
postgres:15-alpine

MySQL

MySQL

docker run -d
--name dev-mysql
-e MYSQL_ROOT_PASSWORD=localdev
-e MYSQL_DATABASE=myapp_dev
-p 3306:3306
-v mysqldata:/var/lib/mysql
mysql:8
docker run -d
--name dev-mysql
-e MYSQL_ROOT_PASSWORD=localdev
-e MYSQL_DATABASE=myapp_dev
-p 3306:3306
-v mysqldata:/var/lib/mysql
mysql:8

MongoDB

MongoDB

docker run -d
--name dev-mongo
-p 27017:27017
-v mongodata:/data/db
mongo:7
docker run -d
--name dev-mongo
-p 27017:27017
-v mongodata:/data/db
mongo:7

Redis

Redis

docker run -d
--name dev-redis
-p 6379:6379
redis:7-alpine

---
docker run -d
--name dev-redis
-p 6379:6379
redis:7-alpine

---

Production Patterns

生产模式

Health Checks

健康检查

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

Health check endpoint

健康检查端点

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3
CMD node healthcheck.js
EXPOSE 3000 CMD ["node", "server.js"]

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

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

const request = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

request.on('error', () => process.exit(1));
request.end();
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3
CMD node healthcheck.js
EXPOSE 3000 CMD ["node", "server.js"]

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

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

const request = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

request.on('error', () => process.exit(1));
request.end();

Security Best Practices

安全最佳实践

dockerfile
FROM python:3.11-slim
dockerfile
FROM python:3.11-slim

1. Use non-root user

1. 使用非root用户

RUN groupadd -r appuser && useradd -r -g appuser appuser
RUN groupadd -r appuser && useradd -r -g appuser appuser

2. Install dependencies as root

2. 以root身份安装依赖

WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt

3. Copy application files

3. 复制应用文件

COPY --chown=appuser:appuser . .
COPY --chown=appuser:appuser . .

4. Switch to non-root user

4. 切换到非root用户

USER appuser
USER appuser

5. Drop unnecessary privileges

5. 丢弃不必要的权限

EXPOSE 8000 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

**Additional Security Measures**:
- Use minimal base images (alpine, distroless)
- Scan images for vulnerabilities: `docker scan myapp:latest`
- Don't include secrets in images (use environment variables or secret managers)
- Keep base images updated
- Use read-only root filesystem when possible
EXPOSE 8000 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

**额外安全措施**:
- 使用最小化基础镜像(alpine、distroless)
- 扫描镜像漏洞:`docker scan myapp:latest`
- 不要在镜像中包含密钥(使用环境变量或密钥管理器)
- 保持基础镜像更新
- 尽可能使用只读根文件系统

Secrets Management

密钥管理

bash
undefined
bash
undefined

Docker Swarm secrets (production)

Docker Swarm密钥(生产环境)

echo "db_password_here" | docker secret create db_password -

```yaml
version: '3.8'
services:
  app:
    image: myapp
    secrets:
      - db_password
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    external: true
Alternative: Environment Files
yaml
undefined
echo "db_password_here" | docker secret create db_password -

```yaml
version: '3.8'
services:
  app:
    image: myapp
    secrets:
      - db_password
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    external: true
替代方案:环境文件
yaml
undefined

docker-compose.yml

docker-compose.yml

services: app: env_file: - .env.production # Never commit this file

```bash
services: app: env_file: - .env.production # 切勿提交此文件

```bash

.env.production (gitignored)

.env.production(已加入git忽略)

DATABASE_URL=postgresql://user:pass@db:5432/prod SECRET_KEY=your-secret-key
undefined
DATABASE_URL=postgresql://user:pass@db:5432/prod SECRET_KEY=your-secret-key
undefined

Resource Limits

资源限制

yaml
services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
bash
undefined
yaml
services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
bash
undefined

Command-line resource limits

命令行资源限制

docker run -d
--memory="512m"
--cpus="1.0"
--restart=unless-stopped
myapp

---
docker run -d
--memory="512m"
--cpus="1.0"
--restart=unless-stopped
myapp

---

Framework-Specific Examples

框架特定示例

Python: Django

Python: Django

dockerfile
FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app
dockerfile
FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

Install system dependencies

安装系统依赖

RUN apt-get update && apt-get install -y
postgresql-client
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
postgresql-client
&& rm -rf /var/lib/apt/lists/*

Install Python dependencies

安装Python依赖

COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt

Copy application

复制应用

COPY . .
COPY . .

Collect static files

收集静态文件

RUN python manage.py collectstatic --noinput
RUN python manage.py collectstatic --noinput

Create non-root user

创建非root用户

RUN useradd -m -u 1000 django && chown -R django:django /app USER django
EXPOSE 8000 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "myproject.wsgi:application"]

**docker-compose.yml**:

```yaml
version: '3.8'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    environment:
      - DEBUG=1
      - DATABASE_URL=postgres://postgres:postgres@db:5432/django_dev
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: django_dev
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
RUN useradd -m -u 1000 django && chown -R django:django /app USER django
EXPOSE 8000 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "myproject.wsgi:application"]

**docker-compose.yml**:

```yaml
version: '3.8'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    environment:
      - DEBUG=1
      - DATABASE_URL=postgres://postgres:postgres@db:5432/django_dev
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: django_dev
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Python: FastAPI

Python: FastAPI

dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

Node.js: Next.js

Node.js: Next.js

dockerfile
undefined
dockerfile
undefined

Multi-stage build for Next.js

Next.js多阶段构建

FROM node:18-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci
FROM node:18-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build
FROM node:18-alpine AS runner WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

**next.config.js** (required for standalone output):

```javascript
module.exports = {
  output: 'standalone',
}
FROM node:18-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci
FROM node:18-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build
FROM node:18-alpine AS runner WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

**next.config.js**(独立输出所需):

```javascript
module.exports = {
  output: 'standalone',
}

Node.js: Express

Node.js: Express

dockerfile
FROM node:18-alpine

WORKDIR /app
dockerfile
FROM node:18-alpine

WORKDIR /app

Install dependencies

安装依赖

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

Copy application

复制应用

COPY . .
COPY . .

Create non-root user

创建非root用户

RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
undefined
RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
undefined

TypeScript Build

TypeScript构建

dockerfile
undefined
dockerfile
undefined

Build stage

构建阶段

FROM node:18-alpine AS builder WORKDIR /app COPY package*.json tsconfig.json ./ RUN npm ci COPY src/ ./src/ RUN npm run build
FROM node:18-alpine AS builder WORKDIR /app COPY package*.json tsconfig.json ./ RUN npm ci COPY src/ ./src/ RUN npm run build

Production stage

生产阶段

FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY --from=builder /app/dist ./dist
EXPOSE 3000 CMD ["node", "dist/index.js"]

---
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY --from=builder /app/dist ./dist
EXPOSE 3000 CMD ["node", "dist/index.js"]

---

Container Orchestration Basics

容器编排基础

Docker Swarm (Built-in)

Docker Swarm(内置)

bash
undefined
bash
undefined

Initialize swarm

初始化swarm

docker swarm init
docker swarm init

Deploy stack

部署栈

docker stack deploy -c docker-compose.yml myapp
docker stack deploy -c docker-compose.yml myapp

Scale service

扩容服务

docker service scale myapp_web=5
docker service scale myapp_web=5

Update service (zero-downtime)

更新服务(零停机)

docker service update --image myapp:2.0 myapp_web
docker service update --image myapp:2.0 myapp_web

Remove stack

删除栈

docker stack rm myapp
undefined
docker stack rm myapp
undefined

Kubernetes Comparison

Kubernetes对比

FeatureDocker ComposeDocker SwarmKubernetes
ComplexityLowMediumHigh
Use CaseLocal devSmall clustersProduction at scale
SetupSingle fileBuilt-inSeparate installation
ScalingManualAutomaticAutomatic + Advanced
HANoYesYes
EcosystemLimitedDockerMassive
When to use each:
  • Docker Compose: Local development, simple deployments
  • Docker Swarm: Small production clusters, simpler than K8s
  • Kubernetes: Large-scale production, multi-cloud, advanced orchestration

特性Docker ComposeDocker SwarmKubernetes
复杂度
适用场景本地开发小型集群大规模生产
设置单文件内置独立安装
扩容手动自动自动+高级功能
高可用
生态系统有限Docker庞大
各工具适用场景:
  • Docker Compose: 本地开发、简单部署
  • Docker Swarm: 小型生产集群,比K8s简单
  • Kubernetes: 大规模生产、多云环境、高级编排

CI/CD Integration

CI/CD集成

GitHub Actions

GitHub Actions

yaml
undefined
yaml
undefined

.github/workflows/docker.yml

.github/workflows/docker.yml

name: Build and Push Docker Image
on: push: branches: [main] pull_request: branches: [main]
env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }}
jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write
steps:
  - uses: actions/checkout@v3

  - name: Log in to Container Registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.REGISTRY }}
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Extract metadata
    id: meta
    uses: docker/metadata-action@v4
    with:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      tags: |
        type=ref,event=branch
        type=semver,pattern={{version}}
        type=sha

  - name: Build and push
    uses: docker/build-push-action@v4
    with:
      context: .
      push: true
      tags: ${{ steps.meta.outputs.tags }}
      labels: ${{ steps.meta.outputs.labels }}
      cache-from: type=gha
      cache-to: type=gha,mode=max

  - name: Run tests
    run: |
      docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} npm test
undefined
name: Build and Push Docker Image
on: push: branches: [main] pull_request: branches: [main]
env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }}
jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write
steps:
  - uses: actions/checkout@v3

  - name: Log in to Container Registry
    uses: docker/login-action@v2
    with:
      registry: ${{ env.REGISTRY }}
      username: ${{ github.actor }}
      password: ${{ secrets.GITHUB_TOKEN }}

  - name: Extract metadata
    id: meta
    uses: docker/metadata-action@v4
    with:
      images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
      tags: |
        type=ref,event=branch
        type=semver,pattern={{version}}
        type=sha

  - name: Build and push
    uses: docker/build-push-action@v4
    with:
      context: .
      push: true
      tags: ${{ steps.meta.outputs.tags }}
      labels: ${{ steps.meta.outputs.labels }}
      cache-from: type=gha
      cache-to: type=gha,mode=max

  - name: Run tests
    run: |
      docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} npm test
undefined

GitLab CI

GitLab CI

yaml
undefined
yaml
undefined

.gitlab-ci.yml

.gitlab-ci.yml

stages:
  • build
  • test
  • deploy
variables: DOCKER_DRIVER: overlay2 IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build: stage: build image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $IMAGE_TAG . - docker push $IMAGE_TAG
test: stage: test script: - docker run --rm $IMAGE_TAG npm test
deploy: stage: deploy script: - docker pull $IMAGE_TAG - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest - docker push $CI_REGISTRY_IMAGE:latest only: - main

---
stages:
  • build
  • test
  • deploy
variables: DOCKER_DRIVER: overlay2 IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build: stage: build image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $IMAGE_TAG . - docker push $IMAGE_TAG
test: stage: test script: - docker run --rm $IMAGE_TAG npm test
deploy: stage: deploy script: - docker pull $IMAGE_TAG - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest - docker push $CI_REGISTRY_IMAGE:latest only: - main

---

Debugging Containers

调试容器

Viewing Logs

查看日志

bash
undefined
bash
undefined

Stream logs

流式查看日志

docker logs -f container_name
docker logs -f container_name

Last 100 lines

最后100行日志

docker logs --tail 100 container_name
docker logs --tail 100 container_name

Logs since timestamp

特定时间戳后的日志

docker logs --since 2024-01-01T10:00:00 container_name
docker logs --since 2024-01-01T10:00:00 container_name

With timestamps

带时间戳的日志

docker logs -t container_name
docker logs -t container_name

Docker Compose logs

Docker Compose日志

docker-compose logs -f service_name
undefined
docker-compose logs -f service_name
undefined

Execute Commands in Running Container

在运行中的容器内执行命令

bash
undefined
bash
undefined

Interactive shell

交互式shell

docker exec -it container_name /bin/sh
docker exec -it container_name /bin/sh

or

docker exec -it container_name /bin/bash
docker exec -it container_name /bin/bash

Run single command

运行单个命令

docker exec container_name ls -la /app
docker exec container_name ls -la /app

Run as different user

以其他用户身份运行

docker exec -u root container_name apt-get update
undefined
docker exec -u root container_name apt-get update
undefined

Inspect Container

检查容器信息

bash
undefined
bash
undefined

Full container details

完整容器详情

docker inspect container_name
docker inspect container_name

Specific field (IP address)

特定字段(IP地址)

docker inspect -f '{{.NetworkSettings.IPAddress}}' container_name
docker inspect -f '{{.NetworkSettings.IPAddress}}' container_name

Environment variables

环境变量

docker inspect -f '{{.Config.Env}}' container_name
docker inspect -f '{{.Config.Env}}' container_name

Mounted volumes

挂载的卷

docker inspect -f '{{.Mounts}}' container_name
undefined
docker inspect -f '{{.Mounts}}' container_name
undefined

Resource Usage

资源使用情况

bash
undefined
bash
undefined

Real-time stats

实时统计

docker stats
docker stats

Single container

单个容器

docker stats container_name
docker stats container_name

No streaming (single snapshot)

非流式(单次快照)

docker stats --no-stream
undefined
docker stats --no-stream
undefined

Network Debugging

网络调试

bash
undefined
bash
undefined

List networks

列出网络

docker network ls
docker network ls

Inspect network

检查网络

docker network inspect bridge
docker network inspect bridge

Test connectivity between containers

测试容器间连通性

docker exec container1 ping container2
docker exec container1 ping container2

Check DNS resolution

检查DNS解析

docker exec container_name nslookup other_container
undefined
docker exec container_name nslookup other_container
undefined

Debugging Build Issues

调试构建问题

bash
undefined
bash
undefined

Build with no cache

无缓存构建

docker build --no-cache -t myapp .
docker build --no-cache -t myapp .

Show build progress

显示构建进度

docker build --progress=plain -t myapp .
docker build --progress=plain -t myapp .

Build specific stage

构建特定阶段

docker build --target builder -t myapp-builder .
docker build --target builder -t myapp-builder .

Inspect intermediate layers

检查中间分层

docker history myapp:latest

---
docker history myapp:latest

---

Local Docker Patterns (mcp-browser, mcp-memory)

本地Docker模式(mcp-browser, mcp-memory)

mcp-browser dev compose

mcp-browser开发compose

  • docker-compose.yml
    runs
    mcp-server
    with a port range
    8875-8895
    and optional
    chrome
    profile.
  • Code mounts are read-only (
    ./src:/app/src:ro
    ) with persistent logs and temp volumes.
  • Environment defaults:
    MCP_DEBUG=true
    ,
    MCP_LOG_LEVEL=DEBUG
    ,
    MCP_HOST=0.0.0.0
    ,
    MCP_PORT=8875
    .
  • Optional profiles:
    chrome
    (browser) and
    tools
    (dev tools container).
  • docker-compose.yml
    运行
    mcp-server
    ,端口范围为
    8875-8895
    ,可选
    chrome
    配置文件。
  • 代码挂载为只读(
    ./src:/app/src:ro
    ),带有持久化日志和临时卷。
  • 默认环境变量:
    MCP_DEBUG=true
    ,
    MCP_LOG_LEVEL=DEBUG
    ,
    MCP_HOST=0.0.0.0
    ,
    MCP_PORT=8875
  • 可选配置文件:
    chrome
    (浏览器)和
    tools
    (开发工具容器)。

mcp-browser Dockerfile.dev

mcp-browser Dockerfile.dev

  • ARG PYTHON_VERSION=3.11
    , install
    watchdog
    + Playwright Chromium.
  • Install package in editable mode and run
    python -m src.dev_runner
    .
  • Non-root user and healthcheck on
    /health
    .
  • ARG PYTHON_VERSION=3.11
    ,安装
    watchdog
    + Playwright Chromium。
  • 以可编辑模式安装包,并运行
    python -m src.dev_runner
  • 使用非root用户,在
    /health
    端点进行健康检查。

mcp-memory production Dockerfile

mcp-memory生产Dockerfile

  • Multi-stage build with venv in
    /opt/venv
    and
    python:3.11-slim
    .
  • Runtime installs
    curl
    for healthcheck, sets
    PYTHONPATH=/app
    .
  • Uses non-root user and
    CMD ["python", "run_api_server.py"]
    with
    /health
    check.
  • 多阶段构建,在
    /opt/venv
    中使用虚拟环境,基础镜像为
    python:3.11-slim
  • 运行时安装
    curl
    用于健康检查,设置
    PYTHONPATH=/app
  • 使用非root用户,使用
    CMD ["python", "run_api_server.py"]
    并在
    /health
    端点进行检查。

Troubleshooting

故障排除

Common Issues

常见问题

"Port already in use"

"端口已被占用"

bash
undefined
bash
undefined

Find process using port

查找占用端口的进程

lsof -i :3000
lsof -i :3000

or

netstat -tulpn | grep 3000
netstat -tulpn | grep 3000

Kill process

终止进程

kill -9 <PID>
kill -9 <PID>

Or use different host port

或使用不同的主机端口

docker run -p 3001:3000 myapp
undefined
docker run -p 3001:3000 myapp
undefined

"Cannot connect to Docker daemon"

"无法连接到Docker守护进程"

bash
undefined
bash
undefined

Check Docker is running

检查Docker是否在运行

docker info
docker info

Restart Docker Desktop (Mac/Windows)

重启Docker Desktop(Mac/Windows)

or

sudo systemctl restart docker # Linux
sudo systemctl restart docker # Linux

Check permissions (Linux)

检查权限(Linux)

sudo usermod -aG docker $USER
sudo usermod -aG docker $USER

Log out and back in

注销后重新登录

undefined
undefined

"No space left on device"

"设备上没有剩余空间"

bash
undefined
bash
undefined

Remove unused containers, images, volumes

删除未使用的容器、镜像、卷

docker system prune -a --volumes
docker system prune -a --volumes

Remove only dangling images

仅删除悬空镜像

docker image prune
docker image prune

Remove stopped containers

删除已停止的容器

docker container prune
docker container prune

Remove unused volumes

删除未使用的卷

docker volume prune
docker volume prune

Check disk usage

检查磁盘使用情况

docker system df
undefined
docker system df
undefined

"Build context too large"

"构建上下文过大"

bash
undefined
bash
undefined

Create .dockerignore

创建.dockerignore

cat > .dockerignore << EOF node_modules/ .git/ *.log dist/ coverage/ EOF
cat > .dockerignore << EOF node_modules/ .git/ *.log dist/ coverage/ EOF

Build with specific context

使用特定上下文构建

docker build -f Dockerfile -t myapp ./src
undefined
docker build -f Dockerfile -t myapp ./src
undefined

Container Exits Immediately

容器立即退出

bash
undefined
bash
undefined

Check logs

查看日志

docker logs container_name
docker logs container_name

Run with interactive shell to debug

运行交互式shell进行调试

docker run -it myapp /bin/sh
docker run -it myapp /bin/sh

Override entrypoint

覆盖入口点

docker run -it --entrypoint /bin/sh myapp
docker run -it --entrypoint /bin/sh myapp

Check exit code

检查退出码

docker inspect -f '{{.State.ExitCode}}' container_name
undefined
docker inspect -f '{{.State.ExitCode}}' container_name
undefined

Permission Denied in Container

容器内权限被拒绝

bash
undefined
bash
undefined

Run as root to debug

以root身份运行进行调试

docker exec -u root -it container_name /bin/sh
docker exec -u root -it container_name /bin/sh

Fix ownership

修复所有权

docker exec -u root container_name chown -R appuser:appuser /app
docker exec -u root container_name chown -R appuser:appuser /app

Or rebuild with correct permissions in Dockerfile

或在Dockerfile中重新构建并设置正确权限

undefined
undefined

Performance Issues

性能问题

Slow Builds

构建缓慢

bash
undefined
bash
undefined

Use BuildKit (faster, better caching)

使用BuildKit(更快,缓存更优)

DOCKER_BUILDKIT=1 docker build -t myapp .
DOCKER_BUILDKIT=1 docker build -t myapp .

Multi-stage builds to reduce layers

使用多阶段构建减少分层

Order instructions by change frequency

按更改频率排序指令

Use .dockerignore to exclude unnecessary files

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

undefined
undefined

High Memory Usage

内存使用率高

bash
undefined
bash
undefined

Set memory limits

设置内存限制

docker run -m 512m myapp
docker run -m 512m myapp

Monitor memory

监控内存使用

docker stats container_name
docker stats container_name

Check for memory leaks in application

检查应用是否存在内存泄漏

undefined
undefined

Slow Volume Mounts (Mac/Windows)

卷挂载缓慢(Mac/Windows)

bash
undefined
bash
undefined

Use delegated consistency (Mac)

使用委托一致性(Mac)

volumes:
  • ./src:/app/src:delegated
volumes:
  • ./src:/app/src:delegated

Or use named volumes instead of bind mounts

或使用命名卷替代绑定挂载

volumes:
  • node_modules:/app/node_modules

---
volumes:
  • node_modules:/app/node_modules

---

Best Practices

最佳实践

Layer Optimization

分层优化

  1. Order by Change Frequency: Least frequently changed first
  2. Combine RUN Commands: Reduce layers
  3. Clean Up in Same Layer: Remove temp files immediately
dockerfile
undefined
  1. 按更改频率排序: 最不常更改的内容放在最前面
  2. 合并RUN命令: 减少分层数量
  3. 在同一分层中清理: 立即删除临时文件
dockerfile
undefined

GOOD

GOOD

RUN apt-get update && apt-get install -y
package1
package2
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
package1
package2
&& rm -rf /var/lib/apt/lists/*

BAD (creates 3 layers, apt cache remains in layer 2)

BAD(创建3个分层,apt缓存保留在第2层)

RUN apt-get update RUN apt-get install -y package1 package2 RUN rm -rf /var/lib/apt/lists/*
undefined
RUN apt-get update RUN apt-get install -y package1 package2 RUN rm -rf /var/lib/apt/lists/*
undefined

Image Size Reduction

镜像体积缩减

  1. Use Alpine Images: 5MB vs 100MB+ for full Linux
  2. Multi-Stage Builds: Exclude build tools from final image
  3. Remove Unnecessary Files: Docs, examples, tests
  4. Use .dockerignore: Exclude development files
dockerfile
undefined
  1. 使用Alpine镜像: 5MB vs 100MB+的完整Linux镜像
  2. 多阶段构建: 最终镜像中排除构建工具
  3. 删除不必要的文件: 文档、示例、测试代码
  4. 使用.dockerignore: 排除开发文件
dockerfile
undefined

Before: 800MB

之前:800MB

FROM node:18 COPY . . RUN npm install CMD ["node", "server.js"]
FROM node:18 COPY . . RUN npm install CMD ["node", "server.js"]

After: 120MB

之后:120MB

FROM node:18-alpine COPY package*.json ./ RUN npm ci --only=production COPY server.js . CMD ["node", "server.js"]
undefined
FROM node:18-alpine COPY package*.json ./ RUN npm ci --only=production COPY server.js . CMD ["node", "server.js"]
undefined

Security Checklist

安全检查清单

  • Use official base images from trusted sources
  • Specify exact image versions (not
    latest
    )
  • Run as non-root user
  • Scan images for vulnerabilities
  • Keep base images updated
  • Don't embed secrets in images
  • Use read-only root filesystem when possible
  • Minimize attack surface (alpine, distroless)
  • Enable Docker Content Trust (image signing)
  • 使用来自可信源的官方基础镜像
  • 指定确切的镜像版本(不要使用
    latest
  • 以非root用户运行
  • 扫描镜像漏洞
  • 保持基础镜像更新
  • 不要在镜像中嵌入密钥
  • 尽可能使用只读根文件系统
  • 最小化攻击面(使用alpine、distroless镜像)
  • 启用Docker内容信任(镜像签名)

Development vs Production

开发 vs 生产

Development:
dockerfile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install  # Include dev dependencies
COPY . .
CMD ["npm", "run", "dev"]
Production:
dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]
开发环境:
dockerfile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install  # 包含开发依赖
COPY . .
CMD ["npm", "run", "dev"]
生产环境:
dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]

Logging Best Practices

日志最佳实践

dockerfile
undefined
dockerfile
undefined

Log to stdout/stderr (Docker captures these)

日志输出到stdout/stderr(Docker会捕获这些)

CMD ["node", "server.js"] # Good
CMD ["node", "server.js"] # 推荐

Don't log to files (lost when container stops)

不要记录到文件(容器停止后会丢失)

CMD ["node", "server.js", ">", "app.log"] # Bad

```javascript
// Application logging
console.log('Info message');   // stdout
console.error('Error message'); // stderr

// Use structured logging
console.log(JSON.stringify({
  level: 'info',
  timestamp: new Date().toISOString(),
  message: 'Request processed',
  requestId: '123'
}));
CMD ["node", "server.js", ">", "app.log"] # 不推荐

```javascript

Environment Configuration

应用日志

dockerfile
undefined
console.log('Info message'); // stdout console.error('Error message'); // stderr

Use ARG for build-time variables

使用结构化日志

ARG NODE_ENV=production ENV NODE_ENV=$NODE_ENV
console.log(JSON.stringify({ level: 'info', timestamp: new Date().toISOString(), message: 'Request processed', requestId: '123' }));
undefined

Use ENV for runtime variables

环境配置

ENV PORT=3000 ENV LOG_LEVEL=info
dockerfile
undefined

Override at runtime

使用ARG设置构建时变量

docker run -e PORT=8080 -e LOG_LEVEL=debug myapp

undefined
ARG NODE_ENV=production ENV NODE_ENV=$NODE_ENV

Health Checks

使用ENV设置运行时变量

dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
yaml
undefined
ENV PORT=3000 ENV LOG_LEVEL=info

docker-compose.yml

运行时覆盖

docker run -e PORT=8080 -e LOG_LEVEL=debug myapp

services: app: image: myapp healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s
undefined
undefined

Graceful Shutdown

健康检查

javascript
// Node.js example
process.on('SIGTERM', () => {
  console.log('SIGTERM received, closing server...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});
dockerfile
undefined
dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
yaml
undefined

Use exec form to properly handle signals

docker-compose.yml

CMD ["node", "server.js"] # Good CMD node server.js # Bad (wrapped in /bin/sh, signals not forwarded)

---
services: app: image: myapp healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s
undefined

Quick Reference

优雅关闭

Essential Commands

bash
undefined
javascript
// Node.js示例
process.on('SIGTERM', () => {
  console.log('收到SIGTERM信号,正在关闭服务器...');
  server.close(() => {
    console.log('服务器已关闭');
    process.exit(0);
  });
});
dockerfile
undefined

Images

使用exec格式以正确处理信号

docker build -t name:tag . docker pull image:tag docker push image:tag docker images docker rmi image:tag
CMD ["node", "server.js"] # 推荐 CMD node server.js # 不推荐(被包裹在/bin/sh中,信号无法转发)

---

Containers

快速参考

核心命令

docker run -d --name container image docker ps # Running containers docker ps -a # All containers docker stop container docker start container docker restart container docker rm container docker logs -f container docker exec -it container /bin/sh
bash
undefined

Cleanup

镜像

docker system prune -a # Remove all unused resources docker container prune # Remove stopped containers docker image prune # Remove dangling images docker volume prune # Remove unused volumes
docker build -t name:tag . docker pull image:tag docker push image:tag docker images docker rmi image:tag

Compose

容器

docker-compose up -d docker-compose down docker-compose logs -f docker-compose exec service /bin/sh docker-compose build
undefined
docker run -d --name container image docker ps # 运行中的容器 docker ps -a # 所有容器 docker stop container docker start container docker restart container docker rm container docker logs -f container docker exec -it container /bin/sh

Common Flags

清理

bash
undefined
docker system prune -a # 删除所有未使用的资源 docker container prune # 删除已停止的容器 docker image prune # 删除悬空镜像 docker volume prune # 删除未使用的卷

docker run flags

Compose

-d # Detached (background) -it # Interactive with TTY -p 8080:80 # Port mapping (host:container) --name myapp # Container name -e VAR=value # Environment variable -v /host:/container # Volume mount --network name # Connect to network --rm # Remove container on exit -m 512m # Memory limit --cpus 1.0 # CPU limit
undefined
docker-compose up -d docker-compose down docker-compose logs -f docker-compose exec service /bin/sh docker-compose build
undefined

Dockerfile Instructions

常用标志

dockerfile
FROM image:tag           # Base image
WORKDIR /path            # Set working directory
COPY src dst             # Copy files
ADD src dst              # Copy (with URL/tar support)
RUN command              # Execute command
ENV KEY=value            # Environment variable
EXPOSE port              # Document port
CMD ["executable"]       # Default command
ENTRYPOINT ["exec"]      # Command prefix
VOLUME /path             # Create mount point
USER username            # Set user
ARG name=default         # Build argument
LABEL key=value          # Metadata
HEALTHCHECK CMD command  # Health check

bash
undefined

Summary

docker run标志

Docker containerization provides:
  • Consistency: Identical environments from dev to production
  • Isolation: Dependencies don't conflict between applications
  • Portability: Run anywhere Docker runs (cloud, local, CI)
  • Efficiency: Lightweight compared to VMs, fast startup
  • Scalability: Easy horizontal scaling with orchestration
Key Workflows:
  1. Development: docker-compose with hot reload volumes
  2. CI/CD: Build, test, push images to registry
  3. Production: Pull images, run with resource limits and health checks
Next Steps:
  • Master multi-stage builds for optimal image sizes
  • Implement health checks and graceful shutdown
  • Set up docker-compose for local development
  • Integrate Docker into CI/CD pipelines
  • Explore orchestration (Swarm or Kubernetes) for production scale
-d # 后台运行(分离模式) -it # 交互式TTY -p 8080:80 # 端口映射(主机:容器) --name myapp # 容器名称 -e VAR=value # 环境变量 -v /host:/container # 卷挂载 --network name # 连接到网络 --rm # 容器退出后自动删除 -m 512m # 内存限制 --cpus 1.0 # CPU限制
undefined

Dockerfile指令

dockerfile
FROM image:tag           # 基础镜像
WORKDIR /path            # 设置工作目录
COPY src dst             # 复制文件
ADD src dst              # 复制(支持URL/压缩包)
RUN command              # 执行命令
ENV KEY=value            # 环境变量
EXPOSE port              # 文档说明端口
CMD ["executable"]       # 默认命令
ENTRYPOINT ["exec"]      # 命令前缀
VOLUME /path             # 创建挂载点
USER username            # 设置用户
ARG name=default         # 构建参数
LABEL key=value          # 元数据
HEALTHCHECK CMD command  # 健康检查

总结

Docker容器化提供:
  • 一致性: 从开发到生产的一致环境
  • 隔离性: 应用间依赖不会冲突
  • 可移植性: 可在任何运行Docker的环境中运行(云、本地、CI)
  • 高效性: 比虚拟机更轻量,启动速度快
  • 可扩展性: 通过编排工具轻松实现水平扩展
核心工作流:
  1. 开发: 使用docker-compose和热重载卷
  2. CI/CD: 构建、测试、推送镜像到仓库
  3. 生产: 拉取镜像,设置资源限制和健康检查后运行
下一步:
  • 掌握多阶段构建以优化镜像体积
  • 实现健康检查和优雅关闭
  • 为本地开发配置docker-compose
  • 将Docker集成到CI/CD流水线
  • 探索编排工具(Swarm或Kubernetes)以实现生产级规模