公司动态
Docker Compose:把多个容器组织成一个应用
Docker Compose把多个容器组织成一个应用一个 SpringBoot 应用通常不会单独运行。它依赖 MySQL 存数据依赖 Redis 做缓存有的还依赖 RabbitMQ、Elasticsearch 等中间件。上一篇讲了如何把单个应用装进容器但实际开发中你需要同时启动这一整套服务。用docker run逐个启动显然不太方便。Docker Compose 提供了一种更适合多服务应用的管理方式。一个 YAML 文件描述所有服务及其依赖关系一条命令全部启动。目录从单个容器到完整应用环境Compose 和 docker run 的关系Compose 如何描述一个应用环境用 Compose 编排 SpringBoot MySQL Redis服务通信容器之间如何通过服务名访问服务启动依赖与健康检查开发环境中的 Compose 常用操作总结从单个容器到完整应用环境一个典型的 SpringBoot 开发环境至少需要这几个服务同时运行SpringBoot 应用 │ ├── MySQL 存储业务数据 ├── Redis 缓存和会话管理 └── RabbitMQ 消息队列可选手动启动这些服务大致是这样的流程# 启动 MySQLdockerrun-d--namemysql\-p3306:3306\-eMYSQL_ROOT_PASSWORDroot123\-eMYSQL_DATABASEmyapp\-vmysql-data:/var/lib/mysql\mysql:8.0# 启动 Redisdockerrun-d--nameredis\-p6379:6379\redis:7# 启动应用dockerrun-d--namemy-app\-p8080:8080\-eSPRING_DATASOURCE_URLjdbc:mysql://mysql:3306/myapp\-eSPRING_REDIS_HOSTredis\my-app:1.0真正麻烦的是配置分散在命令参数中难以维护和复用。每次修改配置要删掉容器重新创建换台机器又要全部重来。服务之间的启动顺序、网络连接、环境变量配置都靠人记住出错了排查也麻烦。Compose 和 docker run 的关系上一篇用docker run启动单个容器这篇用 Compose 管理多个容器。两者不是替代关系而是适用场景不同。docker run适合一次性操作——快速测试一个镜像、临时跑个工具容器、调试某个服务。它的问题是每条命令只管一个容器多个服务之间的配置全靠命令参数传递没有统一的声明文件。docker compose适合需要多个服务协作的场景——开发环境、集成测试、本地 demo。它的核心价值是把所有服务的配置集中到一个 YAML 文件中用一条命令管理整个应用环境。docker rundocker compose管理范围单个容器多个服务配置方式命令参数YAML 文件网络需手动创建和连接自动创建共享网络启动顺序不支持depends_on适用场景临时测试、单服务开发环境、多服务编排日常开发中两者经常配合使用。用docker run快速验证镜像是否能跑确认没问题后再写进docker-compose.yml。Compose 如何描述一个应用环境Compose 用一个 YAML 文件定义所有服务。核心结构services:服务名:image:镜像名ports:-宿主机端口:容器端口environment:-环境变量值volumes:-卷名:容器内路径几个关键字段services定义所有服务每个服务是一个独立的容器image指定使用的镜像。也可以用build指向 Dockerfile让 Compose 自己构建ports端口映射和docker run -p等价environment环境变量和docker run -e等价volumes数据持久化和docker run -v等价Compose 文件不需要记命令参数所有配置都在一个文件里版本管理也方便。用 Compose 编排 SpringBoot MySQL Redis把前面手动启动的三个服务用 Compose 编排services:mysql:image:mysql:8.0ports:-3306:3306environment:MYSQL_ROOT_PASSWORD:root123MYSQL_DATABASE:myappvolumes:-mysql-data:/var/lib/mysqlredis:image:redis:7ports:-6379:6379command:redis-server--requirepass redis123my-app:image:my-app:1.0ports:-8080:8080environment:SPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/myappSPRING_DATASOURCE_USERNAME:rootSPRING_DATASOURCE_PASSWORD:root123SPRING_REDIS_HOST:redisSPRING_REDIS_PASSWORD:redis123depends_on:-mysql-redisvolumes:mysql-data:把这个文件保存为docker-compose.yml在同目录下执行dockercompose up-d三个服务同时启动。docker compose down停止并删除所有容器。Redis 通过command覆盖了默认启动命令加上了密码认证。即使是开发环境也不建议跑无密码的 Redis——配置泄露时没有密码就是裸奔。注意environment中数据库连接地址写的是mysql:3306不是localhost:3306。这是因为 Compose 会自动创建一个网络所有服务都在这个网络中可以直接用服务名互相访问。服务通信容器之间如何通过服务名访问手动docker run时如果不在同一个 Docker 网络中容器之间是无法用名称通信的。Compose 会自动创建网络并将所有服务加入同一个网络。在这个网络中每个服务名就是它的主机名。my-app连接 MySQL 时地址写mysql:3306就能连上不需要知道 MySQL 容器的实际 IP。这也是为什么application.yml中的localhost在容器内不生效容器内的 localhost 指向容器自己不是宿主机也不是其他容器。用 Compose 编排时所有依赖服务的地址都应该写服务名。服务启动依赖与健康检查depends_on只保证启动顺序不保证服务就绪。MySQL 容器启动后还需要几秒钟初始化数据库。如果应用在这几秒内尝试连接会报连接失败。my-app:depends_on:-mysql-redis上面的配置只保证 MySQL 容器先启动但不保证 MySQL 已经准备好接受连接。要等服务真正就绪需要配合健康检查mysql:image:mysql:8.0ports:-3306:3306environment:MYSQL_ROOT_PASSWORD:root123MYSQL_DATABASE:myappvolumes:-mysql-data:/var/lib/mysqlhealthcheck:test:[CMD,mysqladmin,ping,-h,localhost]interval:5stimeout:3sretries:10my-app:image:my-app:1.0ports:-8080:8080environment:SPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/myappSPRING_DATASOURCE_USERNAME:rootSPRING_DATASOURCE_PASSWORD:root123SPRING_REDIS_HOST:redisSPRING_REDIS_PASSWORD:redis123depends_on:mysql:condition:service_healthyredis:condition:service_startedhealthcheck通过mysqladmin ping检测 MySQL 是否就绪。depends_on配合condition: service_healthyCompose 会根据健康检查状态决定是否启动依赖服务后的容器。Redis 启动很快用service_started就够了。MySQL 和 PostgreSQL 这类需要初始化的服务建议都加健康检查。开发环境中的 Compose 常用操作# 启动所有服务后台运行dockercompose up-d# 查看运行状态dockercomposeps# 查看某个服务的日志dockercompose logs my-app# 实时跟踪日志dockercompose logs-fmy-app# 停止所有服务dockercompose down# 停止并删除数据卷慎用会清掉数据库数据dockercompose down-v# 重新构建某个服务的镜像dockercompose build my-app# 重启某个服务dockercompose restart my-app开发中最常用的组合是docker compose up -d启动docker compose logs -f my-app跟踪应用日志docker compose down停止。如果修改了docker-compose.yml需要重新执行docker compose up -dCompose 会自动检测变化并重建受影响的容器。总结Docker Compose 把多个服务的启动、配置和网络连接集中到一个 YAML 文件中。docker compose up -d一条命令启动整套环境docker compose down一条命令全部停止。Compose 自动创建网络容器间用服务名互相访问不需要手动配置 IP。depends_on配合healthcheck可以控制服务启动顺序确保依赖服务就绪后再启动应用。