【Docker容器化部署实战指南:从入门到生产实践】

本文将系统讲解Docker容器化技术,包括镜像构建、容器编排、网络配置、数据持久化等,帮助你掌握现代应用部署的核心技能。

📋 目录


一、Docker核心概念

1.1 Docker架构

复制代码
┌─────────────────────────────────────────┐
│              Docker Client              │
│         (docker build/run/pull)         │
└─────────────────┬───────────────────────┘
                  │ REST API
┌─────────────────▼───────────────────────┐
│              Docker Daemon              │
│              (dockerd)                  │
├─────────────┬───────────┬───────────────┤
│   Images    │ Containers│   Networks    │
├─────────────┼───────────┼───────────────┤
│   Volumes   │  Plugins  │   ...         │
└─────────────┴───────────┴───────────────┘
                  │
┌─────────────────▼───────────────────────┐
│           Docker Registry               │
│        (Docker Hub / 私有仓库)           │
└─────────────────────────────────────────┘

1.2 核心概念对比

概念 说明 类比
镜像(Image) 只读模板,包含运行环境 类的定义
容器(Container) 镜像的运行实例 类的实例
仓库(Registry) 存储和分发镜像 应用商店
Dockerfile 构建镜像的脚本 安装说明书
Volume 数据持久化存储 外接硬盘

1.3 常用命令速查

bash 复制代码
# 镜像操作
docker images                    # 列出镜像
docker pull nginx:latest         # 拉取镜像
docker build -t myapp:v1 .       # 构建镜像
docker rmi image_id              # 删除镜像
docker tag myapp:v1 myapp:latest # 打标签
docker push myrepo/myapp:v1      # 推送镜像

# 容器操作
docker ps                        # 运行中的容器
docker ps -a                     # 所有容器
docker run -d --name web nginx   # 后台运行
docker start/stop/restart web    # 启停容器
docker rm container_id           # 删除容器
docker logs -f web               # 查看日志
docker exec -it web bash         # 进入容器

# 系统操作
docker system df                 # 磁盘使用
docker system prune              # 清理无用资源
docker stats                     # 资源监控

二、镜像构建与优化

2.1 Dockerfile基础

dockerfile 复制代码
# 基础镜像
FROM node:18-alpine

# 元数据
LABEL maintainer="dev@example.com"
LABEL version="1.0"

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制源码
COPY . .

# 构建应用
RUN npm run build

# 暴露端口
EXPOSE 3000

# 环境变量
ENV NODE_ENV=production

# 启动命令
CMD ["node", "dist/server.js"]

2.2 多阶段构建

❌ 错误示例:单阶段构建
dockerfile 复制代码
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/server.js"]
# 问题:镜像包含开发依赖,体积大
✅ 正确示例:多阶段构建
dockerfile 复制代码
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 生产阶段
FROM node:18-alpine AS production
WORKDIR /app

# 只复制生产依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# 从构建阶段复制产物
COPY --from=builder /app/dist ./dist

# 使用非root用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3000
CMD ["node", "dist/server.js"]

2.3 前端项目Dockerfile

dockerfile 复制代码
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 生产阶段 - 使用Nginx
FROM nginx:alpine
# 复制自定义配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx 复制代码
# nginx.conf
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # Gzip压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # SPA路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # API代理
    location /api {
        proxy_pass http://backend:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2.4 镜像优化技巧

dockerfile 复制代码
# 1. 使用Alpine基础镜像
FROM node:18-alpine  # ~170MB vs node:18 ~900MB

# 2. 合并RUN命令减少层数
RUN apk add --no-cache \
    git \
    curl \
    && rm -rf /var/cache/apk/*

# 3. 利用构建缓存 - 先复制依赖文件
COPY package*.json ./
RUN npm ci
COPY . .  # 源码变化不影响依赖缓存

# 4. 使用.dockerignore
# .dockerignore
node_modules
.git
*.md
.env*
dist
coverage

# 5. 清理不必要文件
RUN npm ci --only=production \
    && npm cache clean --force \
    && rm -rf /tmp/*

三、容器管理与网络

3.1 容器运行参数

bash 复制代码
docker run \
  -d \                          # 后台运行
  --name myapp \                # 容器名称
  --restart=unless-stopped \    # 重启策略
  -p 8080:3000 \                # 端口映射
  -v /data:/app/data \          # 数据卷挂载
  -e NODE_ENV=production \      # 环境变量
  --env-file .env \             # 环境变量文件
  -m 512m \                     # 内存限制
  --cpus=1 \                    # CPU限制
  --network mynet \             # 指定网络
  --health-cmd="curl -f http://localhost:3000/health" \
  --health-interval=30s \       # 健康检查
  myapp:latest

3.2 网络模式

bash 复制代码
# 查看网络
docker network ls

# 创建网络
docker network create mynet
docker network create --driver bridge --subnet 172.20.0.0/16 mynet

# 网络模式对比
# bridge: 默认模式,容器间通过网桥通信
# host: 共享主机网络,性能最好
# none: 无网络
# overlay: 跨主机通信(Swarm)

# 容器加入网络
docker network connect mynet container_name
docker network disconnect mynet container_name

# 容器间通信
docker run -d --name db --network mynet mysql
docker run -d --name app --network mynet myapp
# app容器可以通过 db:3306 访问数据库

3.3 容器资源限制

bash 复制代码
# 内存限制
docker run -m 512m --memory-swap 1g myapp

# CPU限制
docker run --cpus=2 myapp           # 最多使用2个CPU
docker run --cpu-shares=512 myapp   # CPU权重

# 查看资源使用
docker stats

# 输出示例
CONTAINER   CPU %   MEM USAGE / LIMIT   MEM %   NET I/O
myapp       0.50%   128MiB / 512MiB     25%     1.2kB / 0B

四、Docker Compose编排

4.1 基础配置

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  # 前端服务
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - app-network

  # 后端服务
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - app-network
    restart: unless-stopped

  # 数据库
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  # Redis缓存
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mysql_data:
  redis_data:

4.2 Compose命令

bash 复制代码
# 启动服务
docker-compose up -d

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs -f backend

# 停止服务
docker-compose stop

# 停止并删除
docker-compose down

# 删除并清理数据卷
docker-compose down -v

# 重新构建
docker-compose build --no-cache
docker-compose up -d --build

# 扩展服务实例
docker-compose up -d --scale backend=3

# 执行命令
docker-compose exec backend sh

4.3 多环境配置

yaml 复制代码
# docker-compose.yml (基础配置)
version: '3.8'
services:
  backend:
    build: ./backend
    environment:
      - NODE_ENV=${NODE_ENV:-development}

# docker-compose.override.yml (开发环境,自动加载)
version: '3.8'
services:
  backend:
    volumes:
      - ./backend:/app
      - /app/node_modules
    ports:
      - "3000:3000"
      - "9229:9229"  # 调试端口
    command: npm run dev

# docker-compose.prod.yml (生产环境)
version: '3.8'
services:
  backend:
    restart: always
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
bash 复制代码
# 开发环境(自动使用override)
docker-compose up

# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

五、数据持久化

5.1 Volume类型

bash 复制代码
# 1. 命名卷(推荐)
docker volume create mydata
docker run -v mydata:/app/data myapp

# 2. 绑定挂载
docker run -v /host/path:/container/path myapp
docker run -v $(pwd)/data:/app/data myapp

# 3. tmpfs挂载(内存)
docker run --tmpfs /app/temp myapp

# 卷管理
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune  # 清理未使用的卷

5.2 数据备份与恢复

bash 复制代码
# 备份数据卷
docker run --rm \
  -v mydata:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/mydata_backup.tar.gz -C /source .

# 恢复数据卷
docker run --rm \
  -v mydata:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/mydata_backup.tar.gz -C /target

# 数据库备份
docker exec mysql mysqldump -u root -p database > backup.sql

# 数据库恢复
docker exec -i mysql mysql -u root -p database < backup.sql

5.3 数据卷最佳实践

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  db:
    image: postgres:15
    volumes:
      # 数据持久化
      - postgres_data:/var/lib/postgresql/data
      # 初始化脚本(只读)
      - ./init:/docker-entrypoint-initdb.d:ro
      # 配置文件
      - ./postgresql.conf:/etc/postgresql/postgresql.conf:ro

  app:
    build: .
    volumes:
      # 上传文件持久化
      - uploads:/app/uploads
      # 日志持久化
      - logs:/app/logs
      # 开发时挂载源码
      - ./src:/app/src:delegated

volumes:
  postgres_data:
    driver: local
  uploads:
  logs:

六、生产环境最佳实践

6.1 安全配置

dockerfile 复制代码
# 1. 使用非root用户
FROM node:18-alpine
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup
USER appuser

# 2. 只读文件系统
docker run --read-only --tmpfs /tmp myapp

# 3. 限制capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp

# 4. 安全扫描
docker scan myapp:latest
trivy image myapp:latest

6.2 健康检查

dockerfile 复制代码
# Dockerfile中配置
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
yaml 复制代码
# docker-compose.yml
services:
  backend:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

6.3 日志管理

yaml 复制代码
# docker-compose.yml
services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
        labels: "production_status"
        env: "os,customer"
bash 复制代码
# 查看日志
docker logs --tail 100 -f container_name

# 日志驱动选项
# json-file: 默认,JSON格式
# syslog: 系统日志
# fluentd: Fluentd收集
# awslogs: AWS CloudWatch
# gelf: Graylog

6.4 CI/CD集成

yaml 复制代码
# .github/workflows/docker.yml
name: Docker Build and Push

on:
  push:
    branches: [main]
    tags: ['v*']

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: |
            myrepo/myapp:latest
            myrepo/myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /app
            docker-compose pull
            docker-compose up -d

6.5 监控与告警

yaml 复制代码
# docker-compose.monitoring.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - "8080:8080"

volumes:
  prometheus_data:
  grafana_data:

📊 Docker命令速查表

类别 命令 说明
镜像 docker build/pull/push 构建/拉取/推送
容器 docker run/start/stop 运行/启停
日志 docker logs -f 实时日志
进入 docker exec -it bash 进入容器
网络 docker network create 创建网络
数据 docker volume create 创建数据卷
清理 docker system prune 清理资源
编排 docker-compose up -d 启动服务

💡 总结

Docker容器化核心要点:

  1. 多阶段构建:减小镜像体积
  2. 合理分层:利用构建缓存
  3. 网络隔离:使用自定义网络
  4. 数据持久化:使用命名卷
  5. 安全加固:非root用户、资源限制
  6. 健康检查:保证服务可用性

掌握Docker,让应用部署更加简单高效!


💬 如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎在评论区讨论~

相关推荐
ulias21216 小时前
Linux系统中的权限问题
linux·运维·服务器
青花瓷18 小时前
Ubuntu下OpenClaw的安装(豆包火山API版)
运维·服务器·ubuntu
问简18 小时前
docker 镜像相关
运维·docker·容器
Dream of maid19 小时前
Linux(下)
linux·运维·服务器
齐鲁大虾19 小时前
统信系统UOS常用命令集
linux·运维·服务器
Benszen19 小时前
Docker容器化技术实战指南
运维·docker·容器
ZzzZZzzzZZZzzzz…19 小时前
Nginx 平滑升级:从 1.26.3 到 1.28.0,用户无感知
linux·运维·nginx·平滑升级·nginx1.26.3·nginx1.28.0
Hommy8820 小时前
【开源剪映小助手】Docker 部署
docker·容器·开源·github·aigc
一叶知秋yyds21 小时前
Ubuntu 虚拟机安装 OpenClaw 完整流程
linux·运维·ubuntu·openclaw
斯普信云原生组21 小时前
Prometheus 环境监控虚机 Redis 方案(生产实操版)
运维·docker·容器