在使用 Docker 部署微服务项目时,通常会结合 Dockerfile 和 docker-compose.yaml 来实现服务的构建与编排。对于你的需求(启动多个服务、有依赖顺序、区分开发/测试/生产环境),我会提供一个完整的解决方案。
[笔记]
-
基本思路 服务依赖顺序:通过 docker-compose 的 depends_on 和健康检查(healthcheck)来控制服务启动顺序。例如,先启动 nacos,待其就绪后再启动 mysql 和 redis,最后启动 gateway、biz 和 web。 环境区分:使用 docker-compose.yaml 配合环境变量文件(如 .env)或多个 docker-compose 文件(如 docker-compose-dev.yaml、docker-compose-prod.yaml)来区分 dev、test 和 prod 环境。 Dockerfile:为每个自定义服务(如 gateway、biz、web)编写 Dockerfile,用于构建镜像。 以下是具体实现步骤和示例代码。
-
项目结构 假设你的项目结构如下:
microservices/
├── nacos/
│ └── Dockerfile (可选,如果需要自定义)
├── gateway/
│ └── Dockerfile
├── biz/
│ └── Dockerfile
├── web/
│ └── Dockerfile
├── docker-compose.yaml
├── docker-compose-dev.yaml
├── docker-compose-prod.yaml
└── .env
- 编写 Dockerfile 对于 gateway、biz 和 web 这类自定义服务,需要编写 Dockerfile 来构建镜像。以 gateway 为例(假设是 Java Spring Boot 项目):
gateway/Dockerfile
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/gateway.jar /app/gateway.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/gateway.jar"]
biz 和 web 的 Dockerfile 类似,只需根据实际端口和 JAR 文件名调整。nacos、mysql 和 redis 通常直接使用官方镜像,无需自定义 Dockerfile,除非有特殊配置需求。
- 编写 docker-compose.yaml 以下是一个基础的 docker-compose.yaml,包含所有服务并处理依赖顺序:
version: '3.8'
services:
nacos:
image: nacos/nacos-server:latest
container_name: nacos
ports:
- "8848:8848"
environment:
- MODE=standalone
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8848/nacos/v1/console/health"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- nacos-data:/home/nacos/data
mysql:
image: mysql:8.0
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: microservices_db
volumes:
- mysql-data:/var/lib/mysql
depends_on:
nacos:
condition: service_healthy
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7.0
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
depends_on:
nacos:
condition: service_healthy
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
gateway:
build:
context: ./gateway
dockerfile: Dockerfile
container_name: gateway
ports:
- "8080:8080"
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
environment:
- SPRING_PROFILES_ACTIVE=${ENV_PROFILE}
biz:
build:
context: ./biz
dockerfile: Dockerfile
container_name: biz
ports:
- "8081:8081"
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
environment:
- SPRING_PROFILES_ACTIVE=${ENV_PROFILE}
web:
build:
context: ./web
dockerfile: Dockerfile
container_name: web
ports:
- "8082:8082"
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
environment:
- SPRING_PROFILES_ACTIVE=${ENV_PROFILE}
volumes:
nacos-data:
mysql-data:
redis-data:
说明:
depends_on 和 healthcheck:确保服务按顺序启动。例如,mysql 和 redis 依赖 nacos 的健康状态,gateway、biz 和 web 依赖 mysql 和 redis。 environment:通过 ${ENV_PROFILE} 动态设置环境(如 dev、prod),具体值在 .env 文件或命令行中指定。 volumes:持久化存储数据,避免容器重启后数据丢失。
- 区分 dev、test、prod 环境
方法 1:使用 .env 文件
创建一个 .env 文件,用于定义环境变量:
.env
ENV_PROFILE=dev
MYSQL_ROOT_PASSWORD=rootpassword
docker-compose up -d
修改 .env 中的 ENV_PROFILE 为 prod 或 test,即可切换环境。服务代码中通过 SPRING_PROFILES_ACTIVE 读取环境配置。
方法 2:使用多个 docker-compose 文件 分别创建 docker-compose-dev.yaml 和 docker-compose-prod.yaml,继承基础的 docker-compose.yaml 并覆盖特定配置。例如:
docker-compose-dev.yaml
version: '3.8'
services:
gateway:
environment:
- SPRING_PROFILES_ACTIVE=dev
biz:
environment:
- SPRING_PROFILES_ACTIVE=dev
web:
environment:
- SPRING_PROFILES_ACTIVE=dev
docker-compose-prod.yaml
version: '3.8'
services:
gateway:
environment:
- SPRING_PROFILES_ACTIVE=prod
biz:
environment:
- SPRING_PROFILES_ACTIVE=prod
web:
environment:
- SPRING_PROFILES_ACTIVE=prod
开发环境
docker-compose -f docker-compose.yaml -f docker-compose-dev.yaml up -d
生产环境
docker-compose -f docker-compose.yaml -f docker-compose-prod.yaml up -d
- 启动与测试 构建并启动所有服务:
docker-compose up -d --build
查看日志,确保服务按顺序启动:
docker-compose logs -f
停止服务:
docker-compose down
- 注意事项
配置 Nacos:确保 gateway、biz 和 web 的配置文件中正确指向 nacos 的地址(例如 nacos:8848)。 网络:默认情况下,docker-compose 会创建一个桥接网络,所有服务可以通过容器名(如 mysql、redis)互相访问。 性能优化:生产环境中,可为 mysql 和 redis 设置资源限制(如 mem_limit、cpus)。 这样,你的微服务项目就可以通过 Docker 部署,并且满足依赖顺序和多环境需求。如果有具体问题或需要调整某部分配置,请告诉我!