用 Docker Compose 一键起本地开发环境
前言
在本地开发 Web 应用时,我们通常需要同时拉起数据库、缓存、消息队列等依赖组件。以前常见的做法是在本机一一安装 MySQL、Redis、RabbitMQ,结果版本冲突、端口打架、环境难以还原。Docker Compose 把多容器编排收敛到一份 YAML 文件里,配合 docker compose up -d 一条命令就能把整组依赖一键启动,本文以一次真实的本地开发环境搭建为例,记录从 compose 文件编写到排错的全流程。
场景设定
一个典型的 Python 后端项目,需要:
- MySQL 8.0 作为主数据库
- Redis 7 作为缓存和会话存储
- 一个 Python 应用容器,通过宿主机挂载代码目录实现热更新
目标:在任意一台装了 Docker 的机器上,执行单条命令即可进入可开发状态。
编写 docker-compose.yml
在项目根目录创建 docker-compose.yml:
services:
mysql:
image: mysql:8.0
container_name: dev-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: devroot123
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: app123
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: dev-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
app:
build:
context: .
dockerfile: Dockerfile
container_name: dev-app
restart: unless-stopped
working_dir: /app
volumes:
- ./:/app
ports:
- "8000:8000"
environment:
DATABASE_URL: mysql+pymysql://app:app123@mysql:3306/app
REDIS_URL: redis://redis:6379/0
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
command: ["python", "main.py"]
volumes:
mysql-data:
redis-data:
几个值得注意的设计选择:
- 用 service 名做网络地址:应用容器连接 MySQL/Redis 时写
mysql和redis,而不是localhost。Compose 默认会创建一张桥接网络,service 名即主机名,容器之间通过内网通信,不暴露端口到宿主机也互不影响。 - healthcheck + service_healthy:
depends_on: condition: service_healthy让 app 容器在依赖真正可连接后再启动,避免 Python 应用一上来就连不上数据库然后崩溃退出的尴尬。 - init.sql 挂载到 initdb 目录:MySQL 官方镜像在首次启动时会自动执行
/docker-entrypoint-initdb.d/下的脚本,适合一次性建表、建初始数据。
Dockerfile 示例
配合上面的 compose,应用容器的 Dockerfile 可以尽量轻量:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8000
CMD ["python", "main.py"]
因为 compose 里已经通过 volumes: ./:/app 挂载了宿主机代码,Dockerfile 只需安装依赖并声明入口;改代码不需要重新 build。
启动与验证
# 后台启动全部服务
docker compose up -d
# 查看各容器状态与健康检查
docker compose ps
# 实时看日志,Ctrl+C 退出不会停容器
docker compose logs -f app
当 docker compose ps 输出中 mysql 和 redis 的 STATUS 列为 healthy、app 为 Up 时,环境就算就绪。此时在宿主机浏览器打开 http://localhost:8000 即可访问应用。
日常运维命令速查
- 只重启某个服务:
docker compose restart app - 拉取最新镜像并重建:
docker compose pull && docker compose up -d --build - 停止并删除容器(保留 volume 数据):
docker compose down - 彻底清理(含数据卷,慎用):
docker compose down -v - 进入容器排查:
docker compose exec mysql bash
常见坑
MySQL 8 认证插件:老版本客户端连 MySQL 8 可能报 caching_sha2_password 错误。在 docker-compose.yml 的 mysql environment 加一行 MYSQL_DEFAULT_AUTHENTICATION_PLUGIN=mysql_native_password 可回退兼容。
权限问题导致热更新不生效:容器内用户 UID 和宿主机不一致时,可能出现文件无法写入。一般开发环境不必较真,但如果报错,可以在 compose 里给 app 加 user: "${UID:-1000}:${GID:-1000}"(配合 .env 传入当前用户的 UID)。
Redis 容器反复重启:redis:7-alpine 默认需要可写的数据目录。上面已经挂载了 redis-data 命名卷,一般不会出现;如果改用 volumes: - ./redis:/data 绑定挂载,要确保 ./redis 目录已存在且权限正确。
总结
用 Docker Compose 拉起本地开发环境的核心思路就三件事:一份声明式 YAML 描述全部依赖、健康检查保证启动顺序、挂载卷保证数据持久和代码热更。把这三件做好了,“一键起本地开发环境” 就不再是口号,而是每天 docker compose up -d 那一秒钟的事。
- 点赞
- 收藏
- 关注作者
评论(0)