Appearance
Docker 高级特性
多阶段构建
多阶段构建允许在单个 Dockerfile 中使用多个构建阶段,可以显著减少最终镜像的大小。
基本多阶段构建示例
docker
# 构建阶段
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 运行阶段
FROM node:16-alpine AS runner
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
RUN npm cache clean --force
# 从构建阶段复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/public ./public
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
带缓存优化的多阶段构建
docker
# 构建阶段
FROM node:16-alpine AS builder
WORKDIR /app
# 先复制依赖文件,利用 Docker 层缓存
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 复制源代码并构建
COPY . .
RUN npm run build
# 生产阶段
FROM node:16-alpine AS production
WORKDIR /app
# 复制依赖(利用缓存)
COPY package*.json ./
RUN npm ci --only=production --omit=dev && npm cache clean --force
# 复制构建产物
COPY --from=builder --chown=node:node /app/dist ./dist
COPY --from=builder --chown=node:node /app/public ./public
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
构建参数和环境变量
构建参数 (ARG)
docker
FROM node:16-alpine
# 定义构建参数
ARG NODE_ENV=production
ARG BUILD_NUMBER=1
ARG COMMIT_SHA=unknown
ENV NODE_ENV=$NODE_ENV
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# 使用构建参数
RUN echo "Building version $BUILD_NUMBER with commit $COMMIT_SHA"
EXPOSE 3000
CMD ["npm", "start"]
构建时传入参数:
bash
docker build \
--build-arg NODE_ENV=production \
--build-arg BUILD_NUMBER=123 \
--build-arg COMMIT_SHA=abc123 \
-t my-app:latest .
环境变量最佳实践
docker
FROM node:16-alpine
# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000
ENV HOST=0.0.0.0
ENV TZ=Asia/Shanghai
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
WORKDIR /app
COPY --chown=nodejs:nodejs package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY --chown=nodejs:nodejs . .
USER nodejs
EXPOSE 3000
CMD ["npm", "start"]
镜像优化技巧
1. 使用 Alpine 镜像
docker
# 使用 Alpine 镜像减小体积
FROM node:16-alpine
# Alpine 镜像需要额外安装依赖
RUN apk add --no-cache \
curl \
bash \
tzdata
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
2. 合并 RUN 指令
docker
FROM node:16-alpine
WORKDIR /app
# 好的做法:合并多个命令
RUN apk add --no-cache curl bash tzdata && \
npm install -g npm@latest && \
mkdir -p /app/logs && \
chmod -R 755 /app/logs
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
3. 使用 .dockerignore 优化
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
*.log
.DS_Store
.vscode
.idea
安全最佳实践
1. 使用非 root 用户
docker
FROM node:16-alpine
# 创建用户和组
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001 -G nodejs
WORKDIR /app
# 以 root 身份安装依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 复制文件并更改所有者
COPY . .
RUN chown -R nodejs:nodejs /app
# 切换到非 root 用户
USER nodejs
EXPOSE 3000
CMD ["npm", "start"]
2. 镜像扫描和安全检查
bash
# 使用 Docker Scout 扫描镜像
docker scout cves my-app:latest
# 使用 Trivy 扫描
trivy image my-app:latest
# 使用 Snyk 扫描
snyk container test my-app:latest
3. 安全的 Dockerfile
docker
FROM node:16-alpine
# 设置安全的环境变量
ENV NODE_ENV=production
ENV NPM_CONFIG_LOGLEVEL=warn
# 创建专用用户
RUN addgroup -g 1001 -S appuser && \
adduser -S appuser -u 1001 -G appuser
# 设置工作目录
WORKDIR /app
# 安装必要的包
RUN apk add --no-cache \
dumb-init \
curl \
ca-certificates
# 复制并安装依赖
COPY package*.json ./
RUN npm ci --only=production --no-audit --no-fund && \
npm cache clean --force
# 复制应用代码
COPY --chown=appuser:appuser . .
# 使用 dumb-init 作为 PID 1
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
# 切换到非 root 用户
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["npm", "start"]
Docker Compose 高级功能
1. 环境变量管理
创建 .env 文件:
NODE_ENV=production
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=user
DB_PASSWORD=password
REDIS_URL=redis://localhost:6379
docker-compose.yml:
yaml
version: '3.8'
services:
app:
build: .
ports:
- "${PORT}:3000"
environment:
- NODE_ENV=${NODE_ENV}
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}
- REDIS_URL=${REDIS_URL}
env_file:
- .env
depends_on:
- db
- redis
db:
image: postgres:13
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "${DB_PORT}:5432"
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
postgres_data:
2. 多配置文件
开发环境配置 docker-compose.dev.yml:
yaml
version: '3.8'
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
- DEBUG=*
ports:
- "3000:3000"
command: ["npm", "run", "dev"]
生产环境配置 docker-compose.prod.yml:
yaml
version: '3.8'
services:
app:
image: my-app:latest
environment:
- NODE_ENV=production
ports:
- "80:3000"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
使用不同配置:
bash
# 开发环境
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
3. 自定义网络
yaml
version: '3.8'
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 内部网络,无法访问外部
services:
app:
build: .
networks:
- frontend
- backend
ports:
- "3000:3000"
db:
image: postgres:13
networks:
- backend
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
nginx:
image: nginx:alpine
networks:
- frontend
ports:
- "80:80"
depends_on:
- app
volumes:
postgres_data:
秘钥管理
1. Docker Secrets (Docker Swarm)
创建秘钥文件:
bash
echo "mysecretpassword" | docker secret create db_password -
在 docker-compose.yml 中使用:
yaml
version: '3.8'
services:
app:
image: my-app:latest
secrets:
- db_password
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
secrets:
db_password:
external: true
2. 环境变量加密
使用 sops 加密环境文件:
bash
# 安装 sops
# 创建加密的 .env 文件
sops --encrypt .env > .env.encrypted
构建缓存优化
1. 利用构建缓存
docker
FROM node:16-alpine
WORKDIR /app
# 1. 先复制依赖文件(变化较少)
COPY package*.json ./
RUN npm ci --only=production
# 2. 复制应用代码(变化较多)
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
2. 构建缓存清理
bash
# 清理构建缓存
docker builder prune
# 清理所有构建缓存
docker builder prune -a
# 构建时跳过缓存
docker build --no-cache -t my-app .
容器运行时优化
1. 资源限制
bash
# 限制内存和 CPU
docker run -m 512m --cpus="1.0" my-app:latest
# 在 docker-compose.yml 中
services:
app:
image: my-app:latest
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
2. 重启策略
yaml
services:
app:
image: my-app:latest
restart: unless-stopped # 或 always, on-failure, no
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Docker Buildx
Docker Buildx 是下一代 Docker 构建工具,支持跨平台构建。
安装和使用 Buildx
bash
# 检查是否支持 buildx
docker buildx version
# 创建构建器实例
docker buildx create --name mybuilder --use
# 构建多平台镜像
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:latest .
# 推送到仓库
docker buildx build --platform linux/amd64,linux/arm64 -t my-app:latest --push .
高级 Buildx 配置
docker
# 使用 BuildKit 功能
# syntax=docker/dockerfile:1.4
FROM node:16-alpine
# 使用缓存挂载
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=production
# 使用 SSH 挂载
RUN --mount=type=ssh \
git clone git@github.com:user/repo.git
# 使用 secret 挂载
RUN --mount=type=secret,id=token \
npm config set '//registry.npmjs.org/:_authToken' $(cat /run/secrets/token)
容器监控和日志
1. 日志配置
yaml
version: '3.8'
services:
app:
image: my-app:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# 或使用其他日志驱动
# driver: "syslog"
# driver: "fluentd"
# driver: "gelf"
2. 健康检查
docker
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["npm", "start"]
总结
Docker 高级特性包括:
- 多阶段构建优化镜像大小
- 构建参数和环境变量管理
- 安全最佳实践
- Docker Compose 高级功能
- 秘钥管理
- 构建缓存优化
- 容器运行时优化
- Buildx 跨平台构建
- 监控和日志配置
这些高级特性可以帮助您构建更安全、更高效、更可维护的容器化应用。