用 Docker Compose 一键起本地开发环境

举报
yd_271806766 发表于 2026/10/22 07:27:32 2026/10/22
【摘要】 前言在本地开发 Web 应用时,我们通常需要同时拉起数据库、缓存、消息队列等依赖组件。以前常见的做法是在本机一一安装 MySQL、Redis、RabbitMQ,结果版本冲突、端口打架、环境难以还原。Docker Compose 把多容器编排收敛到一份 YAML 文件里,配合 docker compose up -d 一条命令就能把整组依赖一键启动,本文以一次真实的本地开发环境搭建为例,记录...

前言

在本地开发 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:

几个值得注意的设计选择:

  1. 用 service 名做网络地址:应用容器连接 MySQL/Redis 时写 mysql 和 redis,而不是 localhost。Compose 默认会创建一张桥接网络,service 名即主机名,容器之间通过内网通信,不暴露端口到宿主机也互不影响。
  2. healthcheck + service_healthy:depends_on: condition: service_healthy 让 app 容器在依赖真正可连接后再启动,避免 Python 应用一上来就连不上数据库然后崩溃退出的尴尬。
  3. 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 那一秒钟的事。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。