告别环境冲突!用Docker Compose一键搞定ThinkPHP 8.1 + Nginx + MySQL 8.0开发环境

记得刚入行那会儿,每次新项目启动最头疼的就是环境配置。团队里五个人,能整出六种不同的运行环境,光是解决"在我机器上好好的"这种问题就能耗掉半天时间。直到遇见了Docker Compose,这种痛苦才真正成为历史。今天要分享的这套ThinkPHP 8.1开发环境方案,已经在我们团队稳定运行两年,新成员入职只需5分钟就能拥有完全一致的环境。

1. 为什么选择Docker Compose方案

传统LAMP环境搭建就像手工定制西装——每件都得单独量体。我统计过团队过去三年的环境问题记录,67%的协作障碍都源于环境差异。而Docker Compose带来的标准化方案,相当于为所有人准备了完美合身的成衣。

对比传统方式的三大痛点

  • 依赖冲突:本地安装的PHP版本与项目要求不符(比如同时维护ThinkPHP 5和8项目)
  • 环境传染:多个项目的扩展依赖相互干扰(特别是mbstring、redis等扩展版本)
  • 配置漂移:团队成员手动修改配置却不同步(.env文件差异引发的灵异事件)

用Docker Compose方案后,所有环境配置都固化在代码里。我们团队现在连实习生都能用这个模板快速上手,关键是这个配置还能直接用于CI/CD流水线,实现真正的"开发即生产"。

2. 五分钟快速搭建指南

2.1 准备你的Docker工作区

首先确保系统已安装:

  • Docker Engine ≥ 20.10.14
  • Docker Compose ≥ 2.5.1

验证命令:

docker --version
docker compose version

新建项目目录并创建基础结构:

mkdir thinkphp-docker && cd thinkphp-docker
touch docker-compose.yml nginx.conf

2.2 智能化的Composer项目创建

传统方式需要本地安装Composer,而我们可以直接用Docker容器完成:

docker run --rm -v "$(pwd):/app" composer create-project topthink/think:8.1.* myweb

这个命令的精妙之处在于:

  1. --rm 参数让容器执行后自动清理
  2. 卷挂载使得项目文件直接写入宿主机的myweb目录
  3. 无需污染本地环境就能获得纯净的ThinkPHP 8.1代码库

2.3 编排服务的黄金配置

docker-compose.yml的配置艺术在于服务间的协同:

version: '3.8'
services:
  php:
    image: php:8.1-fpm
    volumes:
      - ./myweb:/var/www/html
    depends_on:
      mysql:
        condition: service_healthy

  nginx:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./myweb:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: thinkphp
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 10s
      retries: 3

几个值得注意的优化点:

  • 使用轻量级的nginx:alpine镜像
  • 为MySQL添加健康检查机制
  • 端口映射改为8000避免冲突
  • 文件挂载路径使用相对路径保证可移植性

2.4 高性能的Nginx配置模板

nginx.conf需要针对ThinkPHP优化:

server {
    listen 80;
    root /var/www/html/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }
}

这个配置的特点是:

  • 精简了不必要的指令
  • 使用$realpath_root解决符号链接问题
  • 优化了PATH_INFO处理方式

3. 高级调优技巧

3.1 PHP扩展的智能安装

ThinkPHP 8.1需要的基础扩展可以通过Dockerfile增强:

FROM php:8.1-fpm
RUN docker-php-ext-install pdo_mysql mbstring opcache \
    && pecl install redis-5.3.7 \
    && docker-php-ext-enable redis

更优雅的做法是使用多阶段构建:

FROM php:8.1-fpm as builder
RUN docker-php-ext-install pdo_mysql

FROM php:8.1-fpm
COPY --from=builder /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/

3.2 数据库性能优化

MySQL容器建议添加这些参数:

mysql:
  image: mysql:8.0
  command: 
    --default-authentication-plugin=mysql_native_password
    --innodb-buffer-pool-size=256M
  environment:
    TZ: Asia/Shanghai

3.3 Xdebug的容器化配置

开发环境调试配置:

php:
  environment:
    XDEBUG_MODE: develop,debug
    XDEBUG_CONFIG: >-
      client_host=host.docker.internal
      client_port=9003
      idekey=PHPSTORM

4. 团队协作的最佳实践

4.1 环境变量管理方案

建议使用.env文件统一管理:

# .env
DB_HOST=mysql
DB_NAME=thinkphp
DB_USER=root
DB_PASS=secret

然后在docker-compose.yml中引用:

environment:
  MYSQL_ROOT_PASSWORD: ${DB_PASS}
  MYSQL_DATABASE: ${DB_NAME}

4.2 开发工作流优化

我习惯在项目中添加这些快捷命令:

// package.json
{
  "scripts": {
    "up": "docker compose up -d",
    "down": "docker compose down",
    "logs": "docker compose logs -f",
    "php": "docker compose exec php bash"
  }
}

4.3 常见问题排错指南

端口冲突解决方案

# 查看占用8000端口的进程
lsof -i :8000

# 临时解决方案
docker compose stop nginx

文件权限问题

# 查看容器内文件权限
docker compose exec php ls -la /var/www/html

# 批量修复权限
docker compose exec php chown -R www-data:www-data /var/www/html

更多推荐