容器化部署指南
7312 字
预计阅读 30 分钟
容器化技术已成为现代应用部署的标准方案。本指南将全面介绍 Docker 容器化技术和最佳实践。
第一部分:容器化基础
1.1 什么是容器化
容器化是一种操作系统级虚拟化技术,具有以下特点:
- 轻量级:共享主机内核,资源占用少
- 可移植性:一次构建,到处运行
- 隔离性:进程、网络、文件系统隔离
- 一致性:开发、测试、生产环境一致
1.2 Docker 核心概念
镜像 (Image):
- 只读模板,包含运行应用所需的一切
- 分层存储,支持增量更新
- 可以基于其他镜像构建
容器 (Container):
- 镜像的运行实例
- 可写层,运行时产生的数据
- 可以启动、停止、删除
仓库 (Repository):
- 存储镜像的地方
- Docker Hub、私有仓库
- 支持版本管理
第二部分:Docker 基础操作
2.1 安装和配置
安装 Docker:
Bash
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# macOS
brew install docker
# Windows
# 下载 Docker Desktop基础配置:
Bash
# 启动 Docker 服务
sudo systemctl start docker
sudo systemctl enable docker
# 添加用户到 docker 组
sudo usermod -aG docker $USER
# 验证安装
docker --version
docker run hello-world2.2 镜像操作
Bash
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull nginx:latest
docker pull node:18-alpine
# 查看镜像
docker images
docker image ls
# 删除镜像
docker rmi nginx:latest
docker image rm node:18-alpine
# 构建镜像
docker build -t my-app:v1.0 .
docker build -f Dockerfile.prod -t my-app:prod .2.3 容器操作
Bash
# 运行容器
docker run nginx
docker run -d nginx # 后台运行
docker run -p 8080:80 nginx # 端口映射
docker run -v /host:/container nginx # 挂载卷
# 查看容器
docker ps # 运行中的容器
docker ps -a # 所有容器
# 容器管理
docker start container-id
docker stop container-id
docker restart container-id
docker rm container-id
# 进入容器
docker exec -it container-id bash
docker exec -it container-id sh第三部分:Dockerfile 编写
3.1 Dockerfile 基础
基本结构:
Dockerfile
# 基础镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 设置用户
USER node
# 启动命令
CMD ["npm", "start"]3.2 多阶段构建
Dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine AS production
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]3.3 最佳实践
优化镜像大小:
Dockerfile
# 使用 Alpine 基础镜像
FROM node:18-alpine
# 合并 RUN 指令
RUN apk add --no-cache \
git \
python3 \
make \
g++ \
&& npm ci --only=production \
&& npm cache clean --force
# 使用 .dockerignore
# .dockerignore 文件内容:
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
coverage
.nyc_output第四部分:Docker Compose
4.1 Compose 基础
docker-compose.yml 示例:
Yaml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
depends_on:
- db
- redis
volumes:
- ./logs:/app/logs
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
networks:
default:
driver: bridge4.2 Compose 命令
Bash
# 启动服务
docker-compose up
docker-compose up -d # 后台运行
docker-compose up --build # 重新构建
# 停止服务
docker-compose down
docker-compose down -v # 删除卷
# 查看服务
docker-compose ps
docker-compose logs
docker-compose logs -f web # 跟踪日志
# 扩展服务
docker-compose up --scale web=3
# 执行命令
docker-compose exec web bash
docker-compose run web npm test第五部分:生产环境部署
5.1 安全配置
非 root 用户:
Dockerfile
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# 设置文件权限
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs健康检查:
Dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 15.2 环境配置
环境变量管理:
Yaml
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: my-app:latest
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
env_file:
- .env.production
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"5.3 监控和日志
日志配置:
Yaml
services:
web:
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: myapp.web
nginx:
logging:
driver: "syslog"
options:
syslog-address: "tcp://192.168.0.42:123"监控集成:
Yaml
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin第六部分:CI/CD 集成
6.1 GitHub Actions
Yaml
# .github/workflows/docker.yml
name: Docker Build and Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
myapp:latest
myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max6.2 部署脚本
Bash
#!/bin/bash
# deploy.sh
set -e
echo "Pulling latest images..."
docker-compose pull
echo "Stopping services..."
docker-compose down
echo "Starting services..."
docker-compose up -d
echo "Cleaning up..."
docker image prune -f
echo "Deployment completed!"第七部分:故障排除
7.1 常见问题
容器无法启动:
Bash
# 查看容器日志
docker logs container-id
docker logs -f container-id
# 检查容器状态
docker inspect container-id
# 进入容器调试
docker run -it --entrypoint /bin/sh image-name网络问题:
Bash
# 查看网络
docker network ls
docker network inspect bridge
# 测试连接
docker exec container-id ping another-container
docker exec container-id nslookup service-name7.2 性能优化
资源限制:
Yaml
services:
web:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M缓存优化:
Dockerfile
# 利用构建缓存
COPY package*.json ./
RUN npm ci --only=production
# 最后复制代码
COPY . .总结
容器化部署的关键要点:
- 镜像优化:使用多阶段构建,减小镜像大小
- 安全配置:非 root 用户,健康检查
- 环境管理:合理使用环境变量和配置文件
- 监控日志:完善的监控和日志系统
- CI/CD 集成:自动化构建和部署流程