「在我机器上能跑」是开发者最经典的借口。Docker 通过容器化技术,将应用及其依赖打包在一起,实现了「一次构建,到处运行」的承诺。
Docker 核心概念
- 镜像(Image):只读的模板,包含运行应用所需的一切
- 容器(Container):镜像的运行实例,轻量级且相互隔离
- Dockerfile:定义如何构建镜像的文本文件
- Docker Compose:定义和运行多容器应用的工具
编写高效的 Dockerfile
# 多阶段构建 — 减小最终镜像体积
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
Dockerfile 最佳实践
- 使用官方基础镜像,优先选择 Alpine 变体
- 利用多阶段构建分离构建环境和运行环境
- 合理排序 COPY 指令,最大化利用层缓存
- 不要以 root 用户运行容器
- 使用
.dockerignore排除无关文件
Docker Compose 编排
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
pgdata:
CI/CD 集成
在 GitHub Actions 中自动构建和推送 Docker 镜像:
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
常见问题排查
docker logs <container>— 查看容器日志docker exec -it <container> sh— 进入容器调试docker system prune— 清理未使用的资源- 注意容器间网络:使用服务名而非 localhost 通信