【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,让应用部署更加简单高效!


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

相关推荐
夜来小雨2 小时前
SRv6知识点
运维·网络
航Hang*2 小时前
第十三章:网络系统建设与运维(高级)—— 路由控制和策略路由
运维·服务器·网络·笔记·ensp
Run_Teenage2 小时前
Linux:自主Shell命令行解释器
linux·运维·服务器
white-persist2 小时前
【内网运维】Netstat与Wireshark:内网运维溯源实战解析
运维·网络·数据结构·测试工具·算法·网络安全·wireshark
oMcLin2 小时前
Debian 9 内核升级后出现硬件驱动不兼容问题:如何回滚内核与修复驱动
运维·debian
oMcLin2 小时前
Ubuntu 22.04 系统中不明原因的磁盘 I/O 高负载:如何利用 iotop 和 systemd 排查优化
linux·运维·ubuntu
testpassportcn2 小时前
微軟 DP-600 認證介紹|Microsoft Fabric Analytics Engineer Associate 完整解析與考試攻略
运维·fabric
释怀不想释怀2 小时前
打包部署(vue前端)(Nginx)
运维·nginx
fengyehongWorld2 小时前
Linux systemd 与 systemctl 命令
linux·运维·服务器