# 2.7 Docker 快速体验 :::tip 概述 Docker 方案适合快速体验项目功能,无需手动安装 PHP、MySQL 等环境。本文提供完整的 Nginx + PHP-FPM 架构配置,复制即可使用。生产环境部署请参考[第 11 章](/zh/deploy/checklist.html)。 ::: ## 架构说明 ``` 浏览器 → localhost:8000 → [Nginx 容器:80] → [PHP-FPM 容器:9000] → ThinkPHP ↕ [MySQL 容器:3306] + [Redis 容器:6379] ``` ## 文件结构 ``` thinkphp6/ ├── docker-compose.yml # 容器编排(项目根目录) ├── docker/ │ ├── Dockerfile # PHP-FPM 镜像定义 │ ├── nginx.conf # Nginx 站点配置 │ └── .env.docker # 环境变量(密码等) ├── .env # 应用配置 └── ... ``` ## 快速启动 项目已内置完整的 Docker 配置文件(`docker-compose.yml`、`docker/Dockerfile`、`docker/nginx.conf`),无需手动创建,直接启动即可: ```bash # 从官方网站 (https://www.rxthink.cn) 下载授权源码包并解压 cd RXThinkCMF_ThinkPhp8_EleVue # 配置应用环境变量 cp .env.example .env # 编辑 .env,修改数据库连接地址为 Docker 服务名(见下方说明) # 启动所有服务(首次会自动构建镜像,约 2-5 分钟) docker-compose up -d # 查看运行状态 docker-compose ps # 查看日志(确认无报错) docker-compose logs -f app ``` :::tip 说明 `docker-compose.yml` 使用 `${VAR:-默认值}` 语法,未配置 `.env.docker` 时自动使用默认密码(Your_Strong_Password_2024 / Your_Redis_Password_2024),适合快速体验。生产部署请参考[第 11 章](/zh/deploy/docker.html)使用 `--env-file` 指定生产密码。 ::: ## docker-compose.yml 项目根目录的 `docker-compose.yml` 内容如下(供参考,无需手动创建): ```yaml # ============================================================================= # Docker Compose — RXThinkCMF 容器编排 # ============================================================================= # 架构:Nginx(80) → PHP-FPM(9000) → MySQL(3306) + Redis(6379) # # 快速启动(使用默认密码): # docker-compose up -d # # 生产部署(使用 .env.docker 中的密码): # docker-compose --env-file docker/.env.docker up -d --build # ============================================================================= version: '3.8' services: # =========================================================================== # Nginx 反向代理 # =========================================================================== # 接收浏览器请求,静态资源直接返回,.php 请求转发给 PHP-FPM 容器 # =========================================================================== nginx: image: nginx:1.25-alpine container_name: rxthinkcmf-nginx ports: - "${NGINX_PORT:-8000}:80" # 宿主机端口(默认 8000),可通过环境变量覆盖 volumes: - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro # 站点配置(只读) - ./:/var/www/html:ro # 项目代码(只读) depends_on: - app networks: - rxthinkcmf-net restart: unless-stopped # =========================================================================== # PHP-FPM 应用服务 # =========================================================================== # 执行 ThinkPHP 代码,处理 API 请求和业务逻辑 # =========================================================================== app: build: context: . # 构建上下文为项目根目录 dockerfile: docker/Dockerfile # Dockerfile 路径 container_name: rxthinkcmf-app volumes: - ./:/var/www/html # 项目代码(可写) - uploads_data:/opt/data/uploads # 上传文件持久化 environment: - APP_DEBUG=${APP_DEBUG:-true} # 调试模式(快速体验默认开启) depends_on: mysql: condition: service_healthy # 等待 MySQL 就绪 redis: condition: service_started # 等待 Redis 启动 networks: - rxthinkcmf-net restart: unless-stopped # =========================================================================== # MySQL 数据库 # =========================================================================== # 存储业务数据,首次启动自动导入 init.sql # =========================================================================== mysql: image: mysql:8.0 container_name: rxthinkcmf-mysql ports: - "${MYSQL_PORT:-3306}:3306" # 宿主机端口(默认 3306),可通过环境变量覆盖 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-Your_Strong_Password_2024} # root 密码 MYSQL_DATABASE: ${MYSQL_DATABASE:-rxthinkcmf.thinkphp8.elevue} # 自动创建的数据库 MYSQL_CHARSET: utf8mb4 MYSQL_COLLATION: utf8mb4_general_ci volumes: - mysql_data:/var/lib/mysql # 数据持久化 - ./document/mysql/rxthinkcmf.thinkphp8.elevue.sql:/docker-entrypoint-initdb.d/init.sql:ro # 初始化 SQL command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_general_ci - --default-authentication-plugin=mysql_native_password healthcheck: # 健康检查:确保 MySQL 可接受连接 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-Your_Strong_Password_2024}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # MySQL 启动较慢,给 30 秒缓冲 networks: - rxthinkcmf-net restart: unless-stopped # =========================================================================== # Redis 缓存 # =========================================================================== # 提供缓存加速,与 config/cache.php 中的 redis 驱动配合 # =========================================================================== redis: image: redis:7-alpine container_name: rxthinkcmf-redis ports: - "${REDIS_PORT:-6379}:6379" # 宿主机端口(默认 6379),可通过环境变量覆盖 command: redis-server --requirepass ${REDIS_PASSWORD:-Your_Redis_Password_2024} # 访问密码 volumes: - redis_data:/data # 数据持久化 networks: - rxthinkcmf-net restart: unless-stopped # ============================================================================= # 命名卷 — 持久化存储 # ============================================================================= # 容器删除后数据保留,彻底重置请执行:docker-compose down -v # ============================================================================= volumes: mysql_data: # MySQL 数据文件 redis_data: # Redis RDB 快照 uploads_data: # 用户上传文件 # ============================================================================= # 内部网络 # ============================================================================= # 容器间通过服务名(mysql / redis / app)互相访问 # ============================================================================= networks: rxthinkcmf-net: driver: bridge ``` ## Dockerfile 将以下内容保存为 `docker/Dockerfile`: ```dockerfile # ============================================================================= # Dockerfile — PHP-FPM 应用镜像 # ============================================================================= # 基础镜像:PHP 8.2 + FPM # 构建命令:docker-compose build app # ============================================================================= FROM php:8.2-fpm # ----------------------------------------------------------------------------- # 1. 安装系统依赖 # ----------------------------------------------------------------------------- RUN apt-get update && apt-get install -y --no-install-recommends \ libpng-dev \ # GD 扩展 — PNG 支持 libjpeg-dev \ # GD 扩展 — JPEG 支持 libfreetype6-dev \ # GD 扩展 — 字体渲染(验证码) libzip-dev \ # zip 扩展依赖 zip \ # Composer 解压依赖 unzip \ && rm -rf /var/lib/apt/lists/* # ----------------------------------------------------------------------------- # 2. 安装 PHP 扩展 # ----------------------------------------------------------------------------- # pdo_mysql=MySQL驱动 mbstring=多字节 gd=图片 bcmath=高精度 zip=压缩 redis=缓存 RUN docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install -j$(nproc) pdo_mysql mbstring gd bcmath zip \ && pecl install redis \ && docker-php-ext-enable redis # ----------------------------------------------------------------------------- # 3. 安装 Composer # ----------------------------------------------------------------------------- COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # ----------------------------------------------------------------------------- # 4. PHP 生产配置 # ----------------------------------------------------------------------------- RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ && echo '\ date.timezone = Asia/Shanghai\n\ memory_limit = 256M\n\ upload_max_filesize = 50M\n\ post_max_size = 50M\n\ max_execution_time = 60\n\ opcache.enable = 1\n\ opcache.memory_consumption = 256\n\ ' >> "$PHP_INI_DIR/php.ini" # ----------------------------------------------------------------------------- # 5. 安装项目依赖 # ----------------------------------------------------------------------------- WORKDIR /var/www/html COPY composer.json composer.lock ./ RUN composer install --no-dev --optimize-autoloader --no-interaction COPY . . # ----------------------------------------------------------------------------- # 6. 目录权限 # ----------------------------------------------------------------------------- RUN mkdir -p runtime uploads \ && chown -R www-data:www-data runtime uploads \ && chmod -R 775 runtime uploads EXPOSE 9000 CMD ["php-fpm"] ``` ## Nginx 配置 将以下内容保存为 `docker/nginx.conf`: ```nginx # ============================================================================= # Nginx 配置 — ThinkPHP 8 反向代理 # ============================================================================= server { listen 80; server_name localhost; # ThinkPHP 入口目录 root /var/www/html/public; index index.php; # URL 重写(ThinkPHP 路由必需) location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; } } # PHP-FPM 转发("app" 是 docker-compose 中的服务名) location ~ \.php$ { fastcgi_pass app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_read_timeout 300; fastcgi_send_timeout 300; } # 安全:禁止访问隐藏文件 location ~ /\. { deny all; } # 安全:禁止上传目录执行 PHP location ~ /uploads/.*\.php$ { deny all; } # 静态资源缓存 30 天 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 30d; add_header Cache-Control "public, immutable"; } # Gzip 压缩 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml; gzip_min_length 1024; gzip_comp_level 5; } ``` ## 环境变量配置 将以下内容保存为 `docker/.env.docker`: ```ini # Docker 环境变量(密码等敏感信息,切勿提交 Git) MYSQL_ROOT_PASSWORD=Your_Strong_Password_2024 MYSQL_DATABASE=rxthinkcmf.thinkphp8.elevue REDIS_PASSWORD=Your_Redis_Password_2024 APP_DEBUG=false ``` 修改项目根目录 `.env` 文件中的数据库和缓存连接: ```ini [DATABASE] ; 连接地址(Docker 内部使用服务名 "mysql") HOSTNAME = mysql PASSWORD = Your_Strong_Password_2024 [CACHE] ; 连接地址(Docker 内部使用服务名 "redis") REDIS_HOST = redis REDIS_PASSWORD = Your_Redis_Password_2024 [FILE] ; 上传目录(容器内路径) UPLOAD_DIR = /opt/data/uploads ``` ## 访问服务 启动成功后: | 服务 | 地址 | 说明 | |------|------|------| | 后端 API | http://localhost:8000 | Nginx → PHP-FPM → ThinkPHP | | MySQL | localhost:3306 | 用户名 root,密码 Your_Strong_Password_2024 | | Redis | localhost:6379 | 密码 Your_Redis_Password_2024 | 验证后端是否正常: ```bash # 访问首页 curl http://localhost:8000/ # 登录获取 Token curl -X POST http://localhost:8000/api/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456","captcha":"618618"}' ``` ## 常用命令 ```bash # -------------------------------------------------------------------------- # 服务管理 # -------------------------------------------------------------------------- # 启动服务 docker-compose up -d # 停止服务(保留数据) docker-compose down # 停止并清空所有数据(重新开始) docker-compose down -v # 重建镜像(Dockerfile 或 composer.json 变更后) docker-compose up -d --build # -------------------------------------------------------------------------- # 日志排查 # -------------------------------------------------------------------------- # 查看所有日志 docker-compose logs -f # 查看应用日志 docker-compose logs -f app # -------------------------------------------------------------------------- # 进入容器 # -------------------------------------------------------------------------- # 进入 PHP-FPM 容器 docker-compose exec app bash # 进入 MySQL 容器 docker-compose exec mysql bash # -------------------------------------------------------------------------- # 数据库操作 # -------------------------------------------------------------------------- # 导入 SQL(手动方式) docker-compose exec -T mysql mysql -uroot -pYour_Strong_Password_2024 rxthinkcmf.thinkphp8.elevue < document/mysql/rxthinkcmf.thinkphp8.elevue.sql # 进入 MySQL 命令行 docker-compose exec mysql mysql -uroot -pYour_Strong_Password_2024 rxthinkcmf.thinkphp8.elevue # -------------------------------------------------------------------------- # ThinkPHP 命令 # -------------------------------------------------------------------------- # 清除缓存 docker-compose exec app php think clear # 查看路由 docker-compose exec app php think route:list ``` ## 常见问题 ### 端口被占用 ```bash # Windows 查看占用端口的进程 netstat -ano | findstr :8000 # Linux/Mac lsof -i :8000 # 解决方案:修改 docker-compose.yml 中的端口映射 # ports: # - "8080:80" # 改为 8080 ``` ### 数据库连接失败 确认 `.env` 中 `[DATABASE]` 下 `HOSTNAME = mysql`(Docker 服务名),不是 `127.0.0.1`。 ### 容器启动后立即退出 ```bash # 查看退出原因 docker-compose logs app # 常见原因: # 1. PHP 扩展缺失 → 检查 Dockerfile 中的 docker-php-ext-install # 2. 目录权限问题 → 确认 runtime 和 uploads 目录可写 # 3. composer install 失败 → 检查网络或镜像源 ``` ### 重新开始 ```bash # 删除所有容器、网络、数据卷,完全重来 docker-compose down -v docker-compose up -d --build ``` ## 相关文档 - [生产部署](/zh/deploy/docker.html) — 生产环境完整方案 - [后端启动](/zh/quickstart/backend-start.html) — 不用 Docker,手动启动 - [数据库初始化](/zh/quickstart/database-init.html) — 手动导入 SQL