本文记录一套 Docker Compose 基础服务升级前的检查流程,适用于开发环境、小团队测试机、自托管服务和轻量业务系统。核心对象是 MySQL、Postgres、Redis 这类有状态服务。
目标不是讲 Docker Compose 入门,而是避免这类事故:
- Compose 项目换目录后,数据库像新装的一样。
- 执行
docker compose down -v后,命名卷也被移除。 - 旧环境用了匿名卷,新环境没有挂回旧数据。
- MySQL/Postgres 有备份文件,但没有恢复演练。
- Redis 默认当缓存用,实际业务却依赖它的状态。
1. 先分清三类对象
| 对象 | 典型命令 | 升级时怎么处理 |
|---|---|---|
| 镜像 | docker pull |
固定 tag,提前预拉 |
| 容器 | docker compose up -d |
可重建,检查环境变量和端口 |
| 数据卷 | docker volume inspect |
先备份,再恢复验证 |
数据库容器最重要的不是容器 ID,而是数据目录背后的 volume。
2. down 和 down -v 的区别
docker compose down 会停止并移除容器、网络等资源,但默认不会删除命名卷。带上 -v 后,会移除 Compose 文件中声明的命名卷和匿名卷。
建议维护脚本里不要随手写:
bash
docker compose down -v
除非你确认这是一次彻底销毁环境,并且数据已经备份、恢复也验证过。
3. 推荐写稳定命名卷
Postgres 示例:
yaml
services:
db:
image: docker.1ms.run/postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: change-me
POSTGRES_DB: app
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
MySQL 示例:
yaml
services:
mysql:
image: docker.1ms.run/mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: change-me
MYSQL_DATABASE: app
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
Redis 示例:
yaml
services:
redis:
image: docker.1ms.run/redis:7
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
volumes:
redis-data:
这里的重点是:数据库目录必须挂到稳定的命名卷或明确路径,不要靠匿名卷碰运气。
4. 升级前检查命令
查看最终配置:
bash
docker compose config
查看当前卷:
bash
docker volume ls
查看卷详情:
bash
docker volume inspect 项目名_db-data
查看服务使用的挂载:
bash
docker inspect 容器名 --format '{{json .Mounts}}'
如果看到数据库写在匿名卷里,先停下来处理迁移,不要直接升级。
5. MySQL 备份和恢复
备份:
bash
docker compose exec db sh -c 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" app' > mysql-app.sql
恢复验证:
bash
cat mysql-app.sql | docker compose exec -T db sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" app'
注意点:
- 不要只备份 volume tar 包就结束。
- 逻辑备份更容易跨环境验证。
- 大版本升级前先在临时环境导入一次。
6. Postgres 备份和恢复
备份:
bash
docker compose exec -T db pg_dump -U app app > pg-app.sql
恢复验证:
bash
cat pg-app.sql | docker compose exec -T db psql -U app app
注意点:
POSTGRES_USER、POSTGRES_DB、POSTGRES_PASSWORD要和恢复命令一致。- 跨大版本升级时,先看官方镜像关于
PGDATA和数据目录的说明。 - 生产大库需要更严肃的备份方案,本文只覆盖 Compose 小环境和轻量维护。
7. Redis 要先判断是不是状态服务
Redis 如果只是缓存,重建影响可能可控。如果承载队列、会话、任务状态,就要明确持久化策略。
建议检查:
bash
docker compose exec redis redis-cli CONFIG GET appendonly
docker compose exec redis redis-cli CONFIG GET dir
需要持久化时,至少确认:
/data已挂载到稳定卷。- RDB 或 AOF 策略符合业务预期。
- 没有把无密码 Redis 暴露到公网。
8. 镜像预检放在恢复演练之后
维护窗口前可以先拉固定版本镜像:
bash
docker pull docker.1ms.run/postgres:16
docker pull docker.1ms.run/mysql:8.4
docker pull docker.1ms.run/redis:7
docker pull docker.1ms.run/adminer:latest
毫秒镜像(1ms.run)在这里解决的是镜像预检问题:数据库镜像、管理工具镜像和业务基础镜像别到维护窗口才开始拉。它不替代备份,也不替代恢复验证。
9. 最终检查表
| 步骤 | 检查项 | 通过标准 |
|---|---|---|
| 1 | docker compose config |
卷、端口、环境变量清楚 |
| 2 | docker volume ls |
关键数据卷有稳定名字 |
| 3 | docker volume inspect |
挂载点和项目标签确认 |
| 4 | 逻辑备份 | MySQL/Postgres 有可迁移备份 |
| 5 | 恢复演练 | 临时环境能导入 |
| 6 | Redis 策略 | 明确缓存还是状态服务 |
| 7 | 镜像预拉 | 固定 tag 能拉取 |
| 8 | 回滚记录 | 旧镜像 tag 和旧备份可用 |
总结
Docker Compose 让容器重建变得很轻,但有状态服务不能按无状态服务处理。升级前先确认数据卷、备份、恢复演练,再处理镜像预检和服务重启。这个顺序不复杂,但能避开很多低级事故。