banner
NEWS LETTER

Docker Compose 本地开发环境:数据库、缓存、服务和调试

Scroll down

一、为什么本地开发需要 Compose

后端项目通常不只是一个应用进程,还依赖数据库、缓存、消息队列、对象存储、搜索引擎等组件。如果每个成员都手动安装,环境差异会越来越大。

Docker Compose 的价值是把这些依赖写成一份可执行的环境说明。

适合放进 Compose 的内容:

  • MySQL、PostgreSQL、Redis、MongoDB。
  • RabbitMQ、Kafka、NATS。
  • MinIO、Elasticsearch。
  • 本地调试用的 mock 服务。
  • 管理工具,如 Adminer、RedisInsight。

不建议放进 Compose 的内容:

  • 密钥管理系统的真实生产凭证。
  • 需要高可用验证的生产拓扑。
  • 开发机资源承受不了的大型集群。

二、一个基础 compose.yml

下面是一个后端服务常见的本地环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
services:
app:
build: .
ports:
- "8080:8080"
environment:
DB_HOST: mysql
DB_PORT: 3306
REDIS_HOST: redis
depends_on:
- mysql
- redis

mysql:
image: mysql:8.4
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
volumes:
- mysql_data:/var/lib/mysql

redis:
image: redis:7
ports:
- "6379:6379"

volumes:
mysql_data:

启动:

1
docker compose up -d

查看状态:

1
docker compose ps

查看日志:

1
docker compose logs -f app

三、服务名就是内网域名

Compose 会给同一个项目里的服务创建默认网络。服务之间可以直接使用服务名访问:

1
2
app -> mysql:3306
app -> redis:6379

所以应用配置里不应该写 localhost 连接数据库。对于容器里的应用来说,localhost 是容器自己,不是宿主机。

四、健康检查

depends_on 只表达启动顺序,不代表依赖已经可用。数据库容器启动后,真正能接收连接还需要一点时间。

可以给数据库加健康检查:

1
2
3
4
5
6
7
8
9
10
mysql:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 20

然后让应用等待依赖健康:

1
2
3
4
app:
depends_on:
mysql:
condition: service_healthy

五、数据卷和初始化脚本

数据库数据建议放到命名卷:

1
2
volumes:
mysql_data:

这样容器重建后数据还在。

初始化 SQL 可以挂载到 MySQL 的入口目录:

1
2
3
4
mysql:
volumes:
- mysql_data:/var/lib/mysql
- ./docker/mysql/init:/docker-entrypoint-initdb.d

注意:初始化脚本通常只在数据目录首次创建时执行。如果数据卷已经存在,修改初始化 SQL 不会自动重跑。

六、配置分层

建议把配置分成三类:

  • compose.yml:通用服务定义。
  • .env:端口、账号、开关等本地变量。
  • compose.override.yml:个人机器上的特殊配置。

示例 .env

1
2
3
APP_PORT=8080
MYSQL_PORT=3306
MYSQL_PASSWORD=root

Compose 中引用:

1
2
3
4
ports:
- "${APP_PORT}:8080"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}

七、调试建议

开发阶段不要把所有东西都做进镜像。常见做法是:

  • 依赖服务用容器跑。
  • 应用可以在 IDE 或命令行直接跑。
  • 应用通过 localhost:3306 连接暴露到宿主机的数据库。

这样断点调试、热重载、文件同步会更舒服。

如果应用也放到容器里跑,可以使用 volume 挂载源码:

1
2
3
4
app:
volumes:
- .:/workspace
working_dir: /workspace

八、清理环境

停止服务:

1
docker compose down

同时删除数据卷:

1
docker compose down -v

删除数据卷会清空数据库,本地调试前要确认没有重要数据。

九、实践清单

  • 服务名用作容器内域名。
  • 端口映射只暴露本地需要访问的服务。
  • 数据库、缓存使用命名卷持久化。
  • 依赖服务加健康检查。
  • 敏感配置不要提交到仓库。
  • 初始化脚本和迁移脚本分清楚。
  • 本地环境脚本要能一键启动和一键清理。
其他文章
目录导航 置顶
  1. 1. 一、为什么本地开发需要 Compose
  2. 2. 二、一个基础 compose.yml
  3. 3. 三、服务名就是内网域名
  4. 4. 四、健康检查
  5. 5. 五、数据卷和初始化脚本
  6. 6. 六、配置分层
  7. 7. 七、调试建议
  8. 8. 八、清理环境
  9. 9. 九、实践清单
请输入关键词进行搜索