这是一份 ECS 上维护 Docker Compose 基础服务的操作记录,场景不算复杂:一个小型业务环境,用 Compose 跑着 app、mysql、redis 和一个反向袋里。说白了,就是日常维护时那些绕不开的活儿——数据库备份、缓存检查、镜像版本锁死、升级前预热,外加万一翻车怎么回滚。

几个维护目标拎一下:
- 固定数据库和缓存的镜像版本,别让“latest”哪天给坑了。
- 确认 MySQL 数据卷的具体位置,别等到备份时才发现路径不对。
- 做一次逻辑备份,并且真的恢复验证一遍——光备份不验证等于没备份。
- 升级前预拉镜像,别在窗口期里干等下载,那段时间能把人急死。
1. 检查最终配置
先跑一把 docker compose config,确认当前生效的 compose 配置长什么样。尤其是 MySQL 服务,建议把命名卷写明确,不要依赖默认的匿名卷,不然后面 volume 名称乱得你认不出来。
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:
2. 检查 volume
用 docker volume ls 看看有哪些卷,再用 docker volume inspect 项目名_mysql-data 确认挂载点。这里有个常见坑:如果项目目录改过,Compose 项目前缀会跟着变,新卷的名字就变了,旧数据可能就丢了。所以这一步别跳过。
3. 备份 MySQL
用 docker compose exec 执行 mysqldump,把备份导出来:
docker compose exec mysql sh -c 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" app' > mysql-app.sql
光备份不够,得恢复验证。跑一遍:
cat mysql-app.sql | docker compose exec -T mysql sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" app'
要是恢复失败,别急着推进升级步骤——先排查用户权限、密码是否一致、数据库名、字符集、MySQL 版本差异这些因素。恢复不通过,升级就是赌运气。
4. 检查 Redis
Redis 的角色决定了处理方式。如果只是缓存,重建一下影响有限,重启就完事。但如果它承载着队列或者会话,那就必须挂载 /data 卷,并确认持久化策略——比如开启 AOF:
services:
redis:
image: docker.1ms.run/redis:7
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
另外别忘了一件事:云服务器上的安全组和端口暴露。Redis 默认端口 6379,千万别直接暴露到公网上,不然就是给黑客送大礼。
5. 预拉镜像
升级前先把目标镜像拉到本地,这样升级过程中就不需要联网下载了:
docker pull docker.1ms.run/mysql:8.4
docker pull docker.1ms.run/redis:7
docker pull docker.1ms.run/nginx:1.27-alpine
确认预拉成功后,再走升级流程:
docker compose pull
docker compose up -d
6. 回滚准备
动手维护之前,把下面这些东西记下来,最好是写成文档或者贴到笔记里:
- 当前使用的旧镜像 tag。
- 此刻生效的
compose.yaml内容(可以 git 提交一份)。 - 数据库备份文件(就是刚才导出的 .sql)。
- 关键 volume 的名称(比如 mysql-data, redis-data)。
- 恢复验证的结果,明确写上“验证通过”还是“失败”以及原因。
小结
在 ECS 上用 Compose 跑服务,说白了就是把镜像、容器、数据卷这三件事分开处理。容器随便重建,镜像随时重拉,但数据卷必须先备份、再验证恢复结果,才能放心操作。维护窗口的精力应该花在升级本身,而不是临时抱佛脚排查备份能不能用。提前做好回滚预案,翻车也不慌。
