Docker

Docker Compose 新手实战:搭建 PHP 8.4 + MySQL 8.4 开发环境

从 Dockerfile、Compose 服务与健康检查开始,搭建可连接、可观察、数据可持久化的 PHP 8.4 + MySQL 8.4 环境。

TY
Tycho
技术博主
• 2026-09-23 • 12 分钟阅读 • 3 次浏览
Docker Compose 新手实战:搭建 PHP 8.4 + MySQL 8.4 开发环境

本教程用两个服务搭建最小开发环境:app 运行 PHP 内置服务器,db 运行 MySQL。重点不是堆砌配置,而是理解容器网络、健康检查和数据卷。

前提:已安装支持 docker compose 的 Docker。以下示例只用于本地练习,不是生产部署模板。

一、准备目录与 PHP 页面

compose-demo/
├── Dockerfile
├── compose.yaml
└── public/
    └── index.php
<?php
$pdo = new PDO(
    'mysql:host=db;dbname=demo;charset=utf8mb4',
    'demo',
    getenv('DB_PASSWORD'),
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

$version = $pdo->query('SELECT VERSION()')->fetchColumn();
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['status' => 'ok', 'mysql' => $version]);

这里数据库主机名是 db,因为 Compose 网络会用服务名做 DNS。容器中的 localhost 只代表当前容器。

二、编写最小 Dockerfile

FROM php:8.4-cli

RUN docker-php-ext-install pdo_mysql
WORKDIR /app
CMD ["php", "-S", "0.0.0.0:8000", "-t", "public"]

三、编写 compose.yaml

services:
  app:
    build: .
    ports:
      - "8080:8000"
    environment:
      DB_PASSWORD: local-demo-password
    volumes:
      - .:/app
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: demo
      MYSQL_USER: demo
      MYSQL_PASSWORD: local-demo-password
      MYSQL_ROOT_PASSWORD: local-root-password
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-plocal-root-password"]
      interval: 5s
      timeout: 3s
      retries: 20

volumes:
  mysql_data:

示例密码仅供本地练习。团队项目应使用未提交的环境文件或 secrets,不要把真实密码写进仓库。

四、启动并逐层验证

docker compose config
docker compose up -d --build
docker compose ps
docker compose logs --tail=100 db
docker compose logs --tail=100 app
curl -i http://127.0.0.1:8080

先用 config 检查合并后的配置。ps 中数据库应为 healthy;curl 应返回 200 和 MySQL 版本。

五、验证数据卷确实持久化

docker compose exec db mysql -udemo -plocal-demo-password demo \
  -e "CREATE TABLE notes(id INT PRIMARY KEY, body VARCHAR(100)); INSERT INTO notes VALUES(1,'kept');"

docker compose down
docker compose up -d
docker compose exec db mysql -udemo -plocal-demo-password demo \
  -e "SELECT * FROM notes;"

最后应仍能查到 kept。普通 down 不删除命名卷;docker compose down -v 会删除卷和数据,执行前必须确认。

常见问题

  • 应用连接被拒绝:等待 db 变为 healthy,并检查应用是否使用服务名 db。
  • 修改环境变量不生效:重新创建相关容器,单纯 restart 不会更新容器配置。
  • 端口冲突:修改宿主机侧端口,例如 8081:8000。
  • 数据库反复重启:查看 db 日志与数据目录权限,不要直接删除卷掩盖根因。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!