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可以控制服务启动顺序确保依赖服务就绪后再启动应用。

相关新闻

解决Matplotlib中文字体显示问题的跨平台方案

解决Matplotlib中文字体显示问题的跨平台方案

1. 问题现象与背景分析最近在Ubuntu 20.04和Windows 10双系统环境下做数据可视化时,遇到了一个典型的中英文字体混排显示问题。当使用Matplotlib的pyplot绘制包含中文标签的图表时,要么直接报错,要么中文显示为方框,要么出现字体错…

2026/10/9 15:37:18 阅读更多 →
业务逻辑漏洞:网络安全中的隐形威胁与防御策略

业务逻辑漏洞:网络安全中的隐形威胁与防御策略

1. 为什么业务逻辑漏洞是网络安全中的"隐形杀手"?我第一次真正意识到业务逻辑漏洞的威力,是在一次企业内部的渗透测试中。按照常规思路,我扫描了所有端口、测试了SQL注入和XSS,结果一无所获。正当准备收工时&#xff0c…

2026/10/5 6:57:21 阅读更多 →
GPT-5.6降价与快速模式:大模型成本优化与分级服务技术解析

GPT-5.6降价与快速模式:大模型成本优化与分级服务技术解析

大家好,我是专注于技术分享的博主。最近,AI领域的一个新动态引起了广泛关注:GPT-5.6模型在定价策略上做出了重大调整,并引入了新的“快速模式”。这不仅仅是价格变化,更可能预示着大模型服务在成本优化、性能分级和开发…

2026/10/12 22:19:13 阅读更多 →

最新新闻

Spark集合操作全解析:union、join、笛卡尔积的原理与性能陷阱

Spark集合操作全解析:union、join、笛卡尔积的原理与性能陷阱

如果你处理过这样一个需求——把两份来源不同的用户数据合并成一份,或者找出最近30天活跃用户和付费用户的重叠人群,又或者把订单表关联到用户维度表上做统计——你大概率会第一时间想到Spark。但在Spark里,“集合”这个概念被拆成了好几组AP…

2026/10/14 4:50:57 阅读更多 →
从123456到密码管理器:弱密码破解原理与账号安全加固指南

从123456到密码管理器:弱密码破解原理与账号安全加固指南

1. 从“123456”说起:这个最熟悉的数字串到底藏了多少坑我敢打赌,看到“123456”这四个字的瞬间,你脑子里闪过的绝对不是一串数字,而是某个网站的登录页、某个多年没改过的密码,或者某次帮亲戚重装系统时顺手敲下的默认…

2026/10/14 4:50:57 阅读更多 →
轻量模型部署实战:3.8B开源模型从能跑到跑稳

轻量模型部署实战:3.8B开源模型从能跑到跑稳

这个标题是我某天半夜临时建的一个内部备忘录。Strata 是我们那边的统一推理服务层,3.8-Flash-Next 是某开源语言模型项目跑出来的一个轻量分支,参数体量不大,但做生产化接入的时候问题一点不比大模型少。后来这句话被同事转述成“Strata 跑 …

2026/10/14 4:50:57 阅读更多 →
Strata平台部署Qwen3.8-Flash-Next实战:从模型加载到接口调优全记录

Strata平台部署Qwen3.8-Flash-Next实战:从模型加载到接口调优全记录

前几天我们内部接到一个挺常见的任务:一台GPU服务器,一个刚拿到的轻量级模型,要在“Strata”这个内部自研的部署平台上跑起来,对外提供HTTP接口,给业务方调用。模型代号叫“Qwen3.8-Flash-Next”,名字看起来…

2026/10/14 4:50:57 阅读更多 →
前端性能优化实战:从浏览器渲染原理到加载与交互调优

前端性能优化实战:从浏览器渲染原理到加载与交互调优

前端性能优化这个话题,我在团队内部讲过很多次,每次讲完都觉得还能再展开不少。最近接了一个业务线的性能专项,把从前端资源加载到交互流畅度这条链路重新捋了一遍,顺手把过程中的经验和踩过的坑整理下来。这篇文章适合两类人看&a…

2026/10/14 4:50:57 阅读更多 →
大模型预判RTL综合PPA:数字前端设计的实时物理实现顾问

大模型预判RTL综合PPA:数字前端设计的实时物理实现顾问

1. 项目概述:这不是又一个“大模型EDA”的概念秀,而是RTL设计流程里真实卡点的破局尝试PPA-RTL——这个标题里没有花哨的缩写游戏,PPA就是功耗(Power)、性能(Performance)、面积(Are…

2026/10/14 4:49:57 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →