别再手动一个个启动容器了!用Docker Compose编排SpringBoot+Redis+PostgreSQL实战
别再手动一个个启动容器了用Docker Compose编排SpringBootRedisPostgreSQL实战每次本地调试SpringBoot微服务时你是否也厌倦了重复执行这些操作先启动PostgreSQL数据库再打开Redis服务最后运行应用——更别提还要确保端口不冲突、环境变量正确加载。我曾在一个紧急迭代中因为手动启动顺序错误导致联调浪费了整整两小时。直到发现Docker Compose这个开发环境管家才真正体会到什么叫做一键启动的开发体验。1. 环境准备从零搭建编排舞台1.1 安装Docker全家桶在开始编排之前需要确保系统已安装Docker引擎和Compose插件v2.x。现代Docker安装包通常已包含Compose只需执行验证命令docker --version docker compose version若需单独安装Compose插件推荐使用官方脚本# Linux/macOS一键安装 sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose提示Windows用户通过Docker Desktop图形界面安装时默认包含Compose无需额外操作1.2 项目结构规划合理的目录结构能避免后期配置混乱。建议采用如下布局springboot-demo/ ├── app/ │ ├── Dockerfile # 应用镜像构建文件 │ ├── target/*.jar # 打包后的SpringBoot应用 │ └── application.yml # 应用配置文件 └── docker-compose.yml # 编排主文件2. 编写核心编排文件2.1 基础版docker-compose.yml下面是一个最小化可运行的编排配置包含应用、Redis和PostgreSQL服务version: 3.8 services: app: build: ./app ports: - 8080:8080 environment: - SPRING_PROFILES_ACTIVEdev - SPRING_REDIS_HOSTredis - SPRING_DATASOURCE_URLjdbc:postgresql://postgres:5432/demo depends_on: - redis - postgres redis: image: redis:7-alpine ports: - 6379:6379 volumes: - redis_data:/data postgres: image: postgres:15-alpine environment: - POSTGRES_USERdemo - POSTGRES_PASSWORDsecret - POSTGRES_DBdemo volumes: - postgres_data:/var/lib/postgresql/data ports: - 5432:5432 volumes: redis_data: postgres_data:关键配置说明depends_on确保数据库和Redis先于应用启动volumes持久化数据库数据避免容器重启丢失environment通过环境变量注入配置与SpringBoot的application.yml配合使用2.2 高级网络配置默认情况下Compose会创建独立网络所有服务通过服务名互访。如需自定义网络配置networks: app_net: driver: bridge ipam: config: - subnet: 172.20.0.0/24 services: app: networks: app_net: ipv4_address: 172.20.0.23. SpringBoot应用适配改造3.1 应用配置调整确保application.yml支持通过环境变量覆盖配置spring: datasource: url: ${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/demo} username: ${POSTGRES_USER:postgres} password: ${POSTGRES_PASSWORD:} redis: host: ${SPRING_REDIS_HOST:localhost}3.2 Dockerfile优化使用多阶段构建减小镜像体积FROM eclipse-temurin:17-jdk-jammy as builder WORKDIR /app COPY . . RUN ./gradlew bootJar FROM eclipse-temurin:17-jre-jammy WORKDIR /app COPY --frombuilder /app/build/libs/*.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]4. 开发流程实战技巧4.1 一键启停操作常用命令组合# 启动所有服务后台模式 docker compose up -d # 查看实时日志支持服务名过滤 docker compose logs -f app # 停止服务但保留数据卷 docker compose stop # 彻底清除含数据卷 docker compose down -v4.2 调试技巧当需要调试应用时可以使用docker compose exec进入容器docker compose exec app bash临时修改配置后重新构建docker compose build app docker compose up -d查看服务依赖关系docker compose config --services4.3 性能优化配置对于生产环境建议添加资源限制services: app: deploy: resources: limits: cpus: 0.5 memory: 512M healthcheck: test: [CMD, curl, -f, http://localhost:8080/actuator/health] interval: 30s timeout: 10s retries: 35. 常见问题排坑指南5.1 服务启动顺序问题虽然depends_on控制容器启动顺序但无法确保服务就绪。推荐使用健康检查services: postgres: healthcheck: test: [CMD-SHELL, pg_isready -U demo] interval: 5s timeout: 3s retries: 10 app: depends_on: postgres: condition: service_healthy5.2 时区与本地开发差异容器内默认使用UTC时区可通过环境变量统一environment: - TZAsia/Shanghai5.3 数据卷权限问题遇到数据库文件权限错误时可添加初始化脚本volumes: postgres_data: driver_opts: type: none device: ./pgdata o: bind6. 进阶多环境配置方案6.1 环境变量文件管理创建.env文件统一管理变量# .env POSTGRES_USERdev_user POSTGRES_PASSWORDdev123 SPRING_PROFILES_ACTIVEdev在docker-compose.yml中引用env_file: - .env6.2 多Compose文件组合针对不同环境创建docker-compose.override.yml# 开发环境加载额外配置 docker compose -f docker-compose.yml -f docker-compose.dev.yml up生产环境配置示例# docker-compose.prod.yml services: app: image: registry.example.com/springboot-demo:${TAG:-latest} deploy: replicas: 3 environment: - SPRING_PROFILES_ACTIVEprod7. 监控与日志管理7.1 集中式日志收集配置Fluentd驱动将日志输出到ELKservices: app: logging: driver: fluentd options: fluentd-address: localhost:24224 tag: springboot.app7.2 性能监控集成在编排文件中添加Prometheus监控services: app: ports: - 8081:8081 # actuator端口 environment: - MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDEhealth,metrics,prometheus prometheus: image: prom/prometheus ports: - 9090:9090 volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml配套的Prometheus配置示例# prometheus.yml scrape_configs: - job_name: springboot metrics_path: /actuator/prometheus static_configs: - targets: [app:8081]8. 安全加固实践8.1 敏感信息管理使用Docker secrets保护数据库密码echo mysecretpassword | docker secret create pg_password -在compose文件中引用services: postgres: environment: POSTGRES_PASSWORD_FILE: /run/secrets/pg_password secrets: - pg_password secrets: pg_password: external: true8.2 网络隔离策略限制服务间不必要的通信networks: backend: internal: true9. CI/CD集成示例9.1 GitHub Actions自动化流程.github/workflows/deploy.yml示例name: Deploy on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - run: docker compose -f docker-compose.yml build - run: docker compose -f docker-compose.yml up -d - run: docker compose ps9.2 镜像构建优化在CI中缓存构建层docker compose build --pull --no-cache \ docker compose push10. 真实项目经验分享在电商项目中我们使用Compose管理了12个微服务联调环境。通过以下配置大幅提升效率资源复用将公共组件Redis/PostgreSQL提取为独立Compose项目快速切换使用profiles功能按需启动服务组services: payment-service: profiles: [payment] extends: file: common-services.yml service: base-app本地开发热重载结合bind mount实现代码实时同步volumes: - ./app/src:/app/src遇到的一个典型问题是Redis连接不稳定最终通过增加健康检查和重试机制解决Bean public LettuceConnectionFactory redisConnectionFactory() { LettuceClientConfiguration config LettuceClientConfiguration.builder() .commandTimeout(Duration.ofSeconds(1)) .shutdownTimeout(Duration.ZERO) .clientResources(ClientResources.builder().build()) .build(); RedisStandaloneConfiguration serverConfig new RedisStandaloneConfiguration(redis, 6379); return new LettuceConnectionFactory(serverConfig, config); }