Skip to content
清晨的一缕阳光
返回

Docker Compose 部署

Docker Compose 部署

Docker Compose 简介

核心概念

服务(Service)

网络(Network)

卷(Volume)

配置(Config)

架构设计

┌─────────────────────────────────────────┐
│         docker-compose.yml              │
│  ┌─────────────────────────────────┐   │
│  │   Services Definition           │   │
│  │   - user-service                │   │
│  │   - order-service               │   │
│  │   - mysql                       │   │
│  │   - redis                       │   │
│  └─────────────────────────────────┘   │
└───────────────────┬─────────────────────┘


┌─────────────────────────────────────────┐
│         Docker Compose Engine           │
└───────────────────┬─────────────────────┘

        ┌───────────┼───────────┐
        │           │           │
        ▼           ▼           ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Container │ │ Container │ │ Container │
│    1      │ │    2      │ │    3      │
└───────────┘ └───────────┘ └───────────┘

快速开始

1. 安装 Docker Compose

Linux

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

macOS

# Docker Desktop 已包含
docker-compose --version

Windows

# Docker Desktop 已包含
docker-compose --version

2. 基础示例

微服务应用

version: '3.8'

services:
  user-service:
    image: user-service:latest
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - DB_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - mysql
      - redis
    networks:
      - microservice-network

  order-service:
    image: order-service:latest
    ports:
      - "8082:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - DB_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - mysql
      - redis
    networks:
      - microservice-network

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: microservice
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - microservice-network

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - microservice-network

networks:
  microservice-network:
    driver: bridge

volumes:
  mysql-data:
  redis-data:

3. 常用命令

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 停止所有服务
docker-compose down

# 重启服务
docker-compose restart

# 重新构建并启动
docker-compose up -d --build

# 执行命令
docker-compose exec user-service bash

# 查看资源使用
docker-compose top

微服务部署

1. Spring Cloud 全家桶

version: '3.8'

services:
  # 服务注册中心
  nacos:
    image: nacos/nacos-server:2.2.0
    container_name: nacos
    environment:
      - MODE=standalone
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_PORT=3306
      - MYSQL_SERVICE_DB_NAME=nacos_config
      - MYSQL_SERVICE_USER=nacos
      - MYSQL_SERVICE_PASSWORD=nacos123
    ports:
      - "8848:8848"
      - "9848:9848"
    depends_on:
      - mysql
    networks:
      - microservice-network

  # 配置中心
  sentinel:
    image: bladex/sentinel-dashboard:1.8.6
    container_name: sentinel
    ports:
      - "8080:8080"
    environment:
      - SENTINEL_USERNAME=sentinel
      - SENTINEL_PASSWORD=sentinel
    networks:
      - microservice-network

  # 网关
  gateway:
    image: gateway:latest
    container_name: gateway
    ports:
      - "80:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - NACOS_SERVER_ADDR=nacos:8848
      - SENTINEL_DASHBOARD_ADDR=sentinel:8080
    depends_on:
      - nacos
      - sentinel
    networks:
      - microservice-network

  # 用户服务
  user-service:
    image: user-service:latest
    container_name: user-service
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - NACOS_SERVER_ADDR=nacos:8848
    depends_on:
      - nacos
      - mysql
      - redis
    networks:
      - microservice-network

  # 订单服务
  order-service:
    image: order-service:latest
    container_name: order-service
    environment:
      - SPRING_PROFILES_ACTIVE=docker
      - NACOS_SERVER_ADDR=nacos:8848
    depends_on:
      - nacos
      - mysql
      - redis
    networks:
      - microservice-network

  # 数据库
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: microservice
    volumes:
      - mysql-data:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - microservice-network

  # Redis
  redis:
    image: redis:7-alpine
    container_name: redis
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - microservice-network

  # 链路追踪
  skywalking-oap:
    image: apache/skywalking-oap-server:9.7.0
    container_name: skywalking-oap
    environment:
      SW_STORAGE: elasticsearch
      SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
    depends_on:
      - elasticsearch
    networks:
      - microservice-network

  skywalking-ui:
    image: apache/skywalking-ui:9.7.0
    container_name: skywalking-ui
    ports:
      - "8088:8080"
    environment:
      SW_OAP_ADDRESS: skywalking-oap:12800
    depends_on:
      - skywalking-oap
    networks:
      - microservice-network

  elasticsearch:
    image: elasticsearch:7.17.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - es-data:/usr/share/elasticsearch/data
    networks:
      - microservice-network

networks:
  microservice-network:
    driver: bridge

volumes:
  mysql-data:
  redis-data:
  es-data:

2. 多环境配置

docker-compose.dev.yml

version: '3.8'

services:
  user-service:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - SPRING_PROFILES_ACTIVE=dev
      - DEBUG_MODE=true
    volumes:
      - ./logs:/app/logs

  order-service:
    build:
      context: ../order-service
      dockerfile: Dockerfile
    environment:
      - SPRING_PROFILES_ACTIVE=dev

docker-compose.prod.yml

version: '3.8'

services:
  user-service:
    image: registry.example.com/user-service:1.0.0
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"

  order-service:
    image: registry.example.com/order-service:1.0.0
    deploy:
      replicas: 3

使用多环境

# 开发环境
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

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

3. 服务健康检查

version: '3.8'

services:
  user-service:
    image: user-service:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot123"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

配置管理

1. 环境变量

.env 文件

# 数据库配置
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=microservice
MYSQL_USER=app
MYSQL_PASSWORD=app123

# Redis 配置
REDIS_PASSWORD=redis123

# 服务配置
SPRING_PROFILES_ACTIVE=docker
NACOS_SERVER_ADDR=nacos:8848

# 版本
USER_SERVICE_VERSION=1.0.0
ORDER_SERVICE_VERSION=1.0.0

使用环境变量

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}

  user-service:
    image: user-service:${USER_SERVICE_VERSION}
    environment:
      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}

2. Config 文件

version: '3.8'

services:
  user-service:
    image: user-service:latest
    configs:
      - source: app-config
        target: /app/config/application.yml
      - source: logback-config
        target: /app/config/logback.xml

configs:
  app-config:
    file: ./config/application.yml
  logback-config:
    file: ./config/logback.xml

3. Secrets 管理

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    secrets:
      - mysql-root-password
      - mysql-database

secrets:
  mysql-root-password:
    file: ./secrets/mysql-root-password.txt
  mysql-database:
    file: ./secrets/mysql-database.txt

网络配置

1. 自定义网络

version: '3.8'

services:
  gateway:
    networks:
      - frontend
      - backend

  user-service:
    networks:
      - backend

  order-service:
    networks:
      - backend

  mysql:
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # 内部网络,不暴露到外部

2. 服务发现

version: '3.8'

services:
  user-service:
    image: user-service:latest
    networks:
      microservice-network:
        aliases:
          - user
          - user-service

  order-service:
    image: order-service:latest
    networks:
      microservice-network:
        aliases:
          - order
          - order-service

networks:
  microservice-network:
    driver: bridge

日志管理

1. 日志驱动

version: '3.8'

services:
  user-service:
    image: user-service:latest
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
        compress: "true"

  order-service:
    image: order-service:latest
    logging:
      driver: "syslog"
      options:
        syslog-address: "udp://logserver:514"

2. 日志收集

version: '3.8'

services:
  filebeat:
    image: elastic/filebeat:8.8.0
    container_name: filebeat
    volumes:
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - microservice-network
    depends_on:
      - elasticsearch

  elasticsearch:
    image: elasticsearch:7.17.0
    environment:
      - discovery.type=single-node
    volumes:
      - es-data:/usr/share/elasticsearch/data

  kibana:
    image: kibana:7.17.0
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_URL=http://elasticsearch:9200

networks:
  microservice-network:
    driver: bridge

volumes:
  es-data:

性能优化

1. 资源限制

version: '3.8'

services:
  user-service:
    image: user-service:latest
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G

  mysql:
    image: mysql:8.0
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 4G

2. 构建优化

Dockerfile

# 多阶段构建
FROM maven:3.8-openjdk-17 AS build
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

docker-compose.yml

version: '3.8'

services:
  user-service:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - MAVEN_OPTS=-Xmx2g
    image: user-service:latest

3. 缓存优化

version: '3.8'

services:
  user-service:
    build:
      context: .
      cache_from:
        - user-service:latest
        - user-service:cache
    image: user-service:latest

监控告警

1. Prometheus 监控

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:v2.45.0
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - microservice-network

  grafana:
    image: grafana/grafana:10.0.0
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - prometheus
    networks:
      - microservice-network

  node-exporter:
    image: prom/node-exporter:v1.6.0
    container_name: node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
    networks:
      - microservice-network

networks:
  microservice-network:
    driver: bridge

volumes:
  prometheus-data:
  grafana-data:

2. 告警规则

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'spring-boot'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['user-service:8080', 'order-service:8080']

  - job_name: 'mysql'
    static_configs:
      - targets: ['mysql:3306']

  - job_name: 'redis'
    static_configs:
      - targets: ['redis:6379']

最佳实践

1. 目录结构

docker/
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── .env
├── config/
│   ├── application.yml
│   └── logback.xml
├── secrets/
│   ├── mysql-root-password.txt
│   └── redis-password.txt
├── mysql/
│   └── init.sql
└── logs/

2. CI/CD 集成

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build and push
        run: |
          docker build -t user-service:${{ github.sha }} .
          docker push registry.example.com/user-service:${{ github.sha }}
      
      - name: Deploy with docker-compose
        run: |
          docker-compose pull
          docker-compose up -d

3. 备份恢复

#!/bin/bash
# backup.sh

# 备份 MySQL
docker-compose exec -T mysql mysqldump -u root -proot123 microservice > backup/mysql-$(date +%Y%m%d).sql

# 备份 Redis
docker-compose exec -T redis redis-cli SAVE

# 压缩备份
tar -czf backup/full-$(date +%Y%m%d).tar.gz backup/

# 清理旧备份
find backup/ -name "*.tar.gz" -mtime +7 -delete

总结

Docker Compose 是微服务本地开发和测试的理想选择,支持多容器应用编排、服务发现、配置管理等功能。

通过合理的配置和优化,可以快速搭建微服务开发环境,提高开发效率。

在生产环境中,建议结合 CI/CD、监控告警等工具,建立完善的部署和运维体系。


分享这篇文章到:

上一篇文章
Spring Boot Actuator 监控端点
下一篇文章
JVM 调优实战指南