docker
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDocker 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.0bash
docker run -p 3000:3000 myapp:1.0Core 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
undefinedDockerfile中的每条指令都会创建一个分层。Docker会缓存未更改的分层以加快构建速度。
dockerfile
undefinedGOOD: 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
undefinedFROM python:3.11-slim
COPY . . # Changes frequently
RUN pip install -r requirements.txt # Reinstalls on every build
undefinedVolumes
卷
Persistent data storage that survives container restarts.
bash
undefined可持久化存储数据,在容器重启后仍能保留。
bash
undefinedNamed 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
undefineddocker run -v /app/data myapp
undefinedNetworks
网络
Containers communicate through Docker networks.
bash
undefined容器通过Docker网络进行通信。
bash
undefinedCreate 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
undefineddockerfile
undefinedBase 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
undefinedENTRYPOINT ["node"]
CMD ["src/server.js"] # ENTRYPOINT的默认参数
undefinedInstruction Order for Cache Efficiency
缓存优化的指令顺序
dockerfile
undefineddockerfile
undefined1. 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/*
gcc
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
gcc
&& rm -rf /var/lib/apt/lists/*
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"]
undefinedENV 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
undefineddockerfile
undefinedBuild 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 surfaceFROM 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
undefineddockerfile
undefinedBuild 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"]
undefinedFROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
undefinedGo Example (Smallest Images)
Go示例(最小镜像)
dockerfile
undefineddockerfile
undefinedBuild 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
undefinedbash
undefinedStart 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
undefineddocker-compose run app npm test
undefinedFull 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_networkyaml
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_networkDevelopment 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 devdockerfile
undefinedyaml
services:
app:
build: .
volumes:
- ./src:/app/src # 同步源代码
- /app/node_modules # 防止覆盖容器的node_modules
command: npm run devdockerfile
undefinedDockerfile.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"]
undefinedFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install # 包含开发依赖
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
undefinedPython (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 --reloadyaml
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 --reloadVS Code Dev Containers
VS Code开发容器
.devcontainer/devcontainer.jsonjson
{
"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.jsonjson
{
"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
undefinedbash
undefinedPostgreSQL
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
--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
--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
--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
--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
--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
--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
--name dev-redis
-p 6379:6379
redis:7-alpine
---docker run -d
--name dev-redis
-p 6379:6379
redis:7-alpine
--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
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
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-slimdockerfile
FROM python:3.11-slim1. 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 possibleEXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
**额外安全措施**:
- 使用最小化基础镜像(alpine、distroless)
- 扫描镜像漏洞:`docker scan myapp:latest`
- 不要在镜像中包含密钥(使用环境变量或密钥管理器)
- 保持基础镜像更新
- 尽可能使用只读根文件系统Secrets Management
密钥管理
bash
undefinedbash
undefinedDocker 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: trueAlternative: Environment Files
yaml
undefinedecho "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
undefineddocker-compose.yml
docker-compose.yml
services:
app:
env_file:
- .env.production # Never commit this file
```bashservices:
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
undefinedDATABASE_URL=postgresql://user:pass@db:5432/prod
SECRET_KEY=your-secret-key
undefinedResource 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: 3bash
undefinedyaml
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: 3bash
undefinedCommand-line resource limits
命令行资源限制
docker run -d
--memory="512m"
--cpus="1.0"
--restart=unless-stopped
myapp
--memory="512m"
--cpus="1.0"
--restart=unless-stopped
myapp
---docker run -d
--memory="512m"
--cpus="1.0"
--restart=unless-stopped
myapp
--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 /appdockerfile
FROM python:3.11-slim
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
WORKDIR /appInstall system dependencies
安装系统依赖
RUN apt-get update && apt-get install -y
postgresql-client
&& rm -rf /var/lib/apt/lists/*
postgresql-client
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
postgresql-client
&& rm -rf /var/lib/apt/lists/*
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
undefineddockerfile
undefinedMulti-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 /appdockerfile
FROM node:18-alpine
WORKDIR /appInstall 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"]
undefinedRUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
undefinedTypeScript Build
TypeScript构建
dockerfile
undefineddockerfile
undefinedBuild 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
undefinedbash
undefinedInitialize 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
undefineddocker stack rm myapp
undefinedKubernetes Comparison
Kubernetes对比
| Feature | Docker Compose | Docker Swarm | Kubernetes |
|---|---|---|---|
| Complexity | Low | Medium | High |
| Use Case | Local dev | Small clusters | Production at scale |
| Setup | Single file | Built-in | Separate installation |
| Scaling | Manual | Automatic | Automatic + Advanced |
| HA | No | Yes | Yes |
| Ecosystem | Limited | Docker | Massive |
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 Compose | Docker Swarm | Kubernetes |
|---|---|---|---|
| 复杂度 | 低 | 中 | 高 |
| 适用场景 | 本地开发 | 小型集群 | 大规模生产 |
| 设置 | 单文件 | 内置 | 独立安装 |
| 扩容 | 手动 | 自动 | 自动+高级功能 |
| 高可用 | 否 | 是 | 是 |
| 生态系统 | 有限 | Docker | 庞大 |
各工具适用场景:
- Docker Compose: 本地开发、简单部署
- Docker Swarm: 小型生产集群,比K8s简单
- Kubernetes: 大规模生产、多云环境、高级编排
CI/CD Integration
CI/CD集成
GitHub Actions
GitHub Actions
yaml
undefinedyaml
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 testundefinedname: 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 testundefinedGitLab CI
GitLab CI
yaml
undefinedyaml
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
undefinedbash
undefinedStream 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
undefineddocker-compose logs -f service_name
undefinedExecute Commands in Running Container
在运行中的容器内执行命令
bash
undefinedbash
undefinedInteractive 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
undefineddocker exec -u root container_name apt-get update
undefinedInspect Container
检查容器信息
bash
undefinedbash
undefinedFull 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
undefineddocker inspect -f '{{.Mounts}}' container_name
undefinedResource Usage
资源使用情况
bash
undefinedbash
undefinedReal-time stats
实时统计
docker stats
docker stats
Single container
单个容器
docker stats container_name
docker stats container_name
No streaming (single snapshot)
非流式(单次快照)
docker stats --no-stream
undefineddocker stats --no-stream
undefinedNetwork Debugging
网络调试
bash
undefinedbash
undefinedList 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
undefineddocker exec container_name nslookup other_container
undefinedDebugging Build Issues
调试构建问题
bash
undefinedbash
undefinedBuild 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
- runs
docker-compose.ymlwith a port rangemcp-serverand optional8875-8895profile.chrome - Code mounts are read-only () with persistent logs and temp volumes.
./src:/app/src:ro - Environment defaults: ,
MCP_DEBUG=true,MCP_LOG_LEVEL=DEBUG,MCP_HOST=0.0.0.0.MCP_PORT=8875 - Optional profiles: (browser) and
chrome(dev tools container).tools
- 运行
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
- , install
ARG PYTHON_VERSION=3.11+ Playwright Chromium.watchdog - Install package in editable mode and run .
python -m src.dev_runner - Non-root user and healthcheck on .
/health
- ,安装
ARG PYTHON_VERSION=3.11+ Playwright Chromium。watchdog - 以可编辑模式安装包,并运行。
python -m src.dev_runner - 使用非root用户,在端点进行健康检查。
/health
mcp-memory production Dockerfile
mcp-memory生产Dockerfile
- Multi-stage build with venv in and
/opt/venv.python:3.11-slim - Runtime installs for healthcheck, sets
curl.PYTHONPATH=/app - Uses non-root user and with
CMD ["python", "run_api_server.py"]check./health
- 多阶段构建,在中使用虚拟环境,基础镜像为
/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
undefinedbash
undefinedFind 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
undefineddocker run -p 3001:3000 myapp
undefined"Cannot connect to Docker daemon"
"无法连接到Docker守护进程"
bash
undefinedbash
undefinedCheck 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
注销后重新登录
undefinedundefined"No space left on device"
"设备上没有剩余空间"
bash
undefinedbash
undefinedRemove 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
undefineddocker system df
undefined"Build context too large"
"构建上下文过大"
bash
undefinedbash
undefinedCreate .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
undefineddocker build -f Dockerfile -t myapp ./src
undefinedContainer Exits Immediately
容器立即退出
bash
undefinedbash
undefinedCheck 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
undefineddocker inspect -f '{{.State.ExitCode}}' container_name
undefinedPermission Denied in Container
容器内权限被拒绝
bash
undefinedbash
undefinedRun 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中重新构建并设置正确权限
undefinedundefinedPerformance Issues
性能问题
Slow Builds
构建缓慢
bash
undefinedbash
undefinedUse 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排除不必要的文件
undefinedundefinedHigh Memory Usage
内存使用率高
bash
undefinedbash
undefinedSet 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
检查应用是否存在内存泄漏
undefinedundefinedSlow Volume Mounts (Mac/Windows)
卷挂载缓慢(Mac/Windows)
bash
undefinedbash
undefinedUse 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
分层优化
- Order by Change Frequency: Least frequently changed first
- Combine RUN Commands: Reduce layers
- Clean Up in Same Layer: Remove temp files immediately
dockerfile
undefined- 按更改频率排序: 最不常更改的内容放在最前面
- 合并RUN命令: 减少分层数量
- 在同一分层中清理: 立即删除临时文件
dockerfile
undefinedGOOD
GOOD
RUN apt-get update && apt-get install -y
package1
package2
&& rm -rf /var/lib/apt/lists/*
package1
package2
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y
package1
package2
&& rm -rf /var/lib/apt/lists/*
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/*
undefinedRUN apt-get update
RUN apt-get install -y package1 package2
RUN rm -rf /var/lib/apt/lists/*
undefinedImage Size Reduction
镜像体积缩减
- Use Alpine Images: 5MB vs 100MB+ for full Linux
- Multi-Stage Builds: Exclude build tools from final image
- Remove Unnecessary Files: Docs, examples, tests
- Use .dockerignore: Exclude development files
dockerfile
undefined- 使用Alpine镜像: 5MB vs 100MB+的完整Linux镜像
- 多阶段构建: 最终镜像中排除构建工具
- 删除不必要的文件: 文档、示例、测试代码
- 使用.dockerignore: 排除开发文件
dockerfile
undefinedBefore: 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"]
undefinedFROM node:18-alpine
COPY package*.json ./
RUN npm ci --only=production
COPY server.js .
CMD ["node", "server.js"]
undefinedSecurity 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 /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 /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]Logging Best Practices
日志最佳实践
dockerfile
undefineddockerfile
undefinedLog 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"] # 不推荐
```javascriptEnvironment Configuration
应用日志
dockerfile
undefinedconsole.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'
}));
undefinedUse ENV for runtime variables
环境配置
ENV PORT=3000
ENV LOG_LEVEL=info
dockerfile
undefinedOverride at runtime
使用ARG设置构建时变量
docker run -e PORT=8080 -e LOG_LEVEL=debug myapp
—
undefinedARG NODE_ENV=production
ENV NODE_ENV=$NODE_ENV
Health Checks
使用ENV设置运行时变量
dockerfile
HEALTHCHECK \
CMD curl -f http://localhost:3000/health || exit 1yaml
undefinedENV 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
undefinedundefinedGraceful Shutdown
健康检查
javascript
// Node.js example
process.on('SIGTERM', () => {
console.log('SIGTERM received, closing server...');
server.close(() => {
console.log('Server closed');
process.exit(0);
});
});dockerfile
undefineddockerfile
HEALTHCHECK \
CMD curl -f http://localhost:3000/health || exit 1yaml
undefinedUse 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
undefinedQuick Reference
优雅关闭
Essential Commands
—
bash
undefinedjavascript
// Node.js示例
process.on('SIGTERM', () => {
console.log('收到SIGTERM信号,正在关闭服务器...');
server.close(() => {
console.log('服务器已关闭');
process.exit(0);
});
});dockerfile
undefinedImages
使用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
undefinedCleanup
镜像
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
undefineddocker 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
undefineddocker 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
undefineddocker-compose up -d
docker-compose down
docker-compose logs -f
docker-compose exec service /bin/sh
docker-compose build
undefinedDockerfile 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 checkbash
undefinedSummary
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:
- Development: docker-compose with hot reload volumes
- CI/CD: Build, test, push images to registry
- 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)
- 高效性: 比虚拟机更轻量,启动速度快
- 可扩展性: 通过编排工具轻松实现水平扩展
核心工作流:
- 开发: 使用docker-compose和热重载卷
- CI/CD: 构建、测试、推送镜像到仓库
- 生产: 拉取镜像,设置资源限制和健康检查后运行
下一步:
- 掌握多阶段构建以优化镜像体积
- 实现健康检查和优雅关闭
- 为本地开发配置docker-compose
- 将Docker集成到CI/CD流水线
- 探索编排工具(Swarm或Kubernetes)以实现生产级规模