import{_ as i,o as a,c as n,a2 as l}from"./chunks/framework.BbmSSMjL.js";const E=JSON.parse('{"title":"2.8 Docker 快速体验","description":"","frontmatter":{},"headers":[],"relativePath":"zh/quickstart/docker.md","filePath":"zh/quickstart/docker.md"}'),p={name:"zh/quickstart/docker.md"};function h(k,s,t,e,r,d){return a(),n("div",null,[...s[0]||(s[0]=[l(`

2.8 Docker 快速体验 ​

概述

Docker 方案适合快速体验项目功能,无需在本机手动安装 PHP、MySQL、Redis 等环境。项目内置完整的 Nginx + PHP-FPM 架构配置,一条命令即可启动,脚本全文见下方(供参考,无需手动创建)。生产环境部署请参考 11.6 Docker 生产部署。

架构说明 ​

text
浏览器 → admin.laravel13.naivevue → [Nginx 容器:80] → [PHP-FPM 容器:9000] → Laravel 应用
                                                ↕
                                    [MySQL 容器:3306] + [Redis 容器:6379]

文件结构 ​

text
RXThinkCMF_Laravel13_NaiveVue/
├── docker-compose.yml          # 容器编排(项目根目录)
├── .dockerignore               # 构建上下文排除(.env、vendor、SQL 等)
├── docker/
│   ├── Dockerfile              # PHP-FPM 镜像定义
│   ├── nginx.conf              # Nginx 站点配置
│   └── .env.docker             # 环境变量(密码等)
├── .env                        # 应用配置(Laravel 读取)
└── ...

前置要求 ​

依赖版本要求说明
Docker Desktop>= 20.10(含 Compose v2)已安装并启动,docker compose version 可验证
项目已初始化根目录存在 .env 且 APP_KEY 已生成未初始化见下方命令
JWT_SECRET.env 中 >= 32 字符应用启动 fail-close 校验,不满足拒绝启动

尚未初始化时,先在宿主机执行(依赖 2.1 开发环境准备 中的 PHP 8.3 + Composer):

bash
composer setup
# 等价于:composer install → 复制 .env → key:generate → migrate --force → npm install → npm run build

快速启动 ​

项目已内置完整的 Docker 配置文件(docker-compose.yml、docker/Dockerfile、docker/nginx.conf),无需手动创建,直接启动即可:

bash
cd RXThinkCMF_Laravel13_NaiveVue

# 启动所有服务(首次会自动构建镜像,约 2-5 分钟)
docker compose up -d

# 查看运行状态(首次 mysql 需导入约 226MB SQL,初始化 1~3 分钟,
# 等到 mysql 变为 healthy,app 依赖健康检查会自动等待)
docker compose ps

# 查看日志(确认无报错)
docker compose logs -f app

说明

docker-compose.yml 使用 \${VAR:-默认值} 语法,未配置 docker/.env.docker 时自动使用默认密码(root123 / redis123),适合快速体验。生产部署请参考 11.6 Docker 生产部署 使用 --env-file 指定生产密码。

端口冲突处理(本机有 Laragon 时) ​

本机 Laragon 已占用 3306(MySQL)/ 6379(Redis)时,修改 docker/.env.docker 中的宿主机端口即可:

ini
NGINX_PORT=8000        # Web 端口(被占用时改为 8080 等)
MYSQL_PORT=3307        # 与 Laragon MySQL 冲突时改为 3307
REDIS_PORT=6380        # 与 Laragon Redis 冲突时改为 6380

容器之间通过服务名(mysql / redis)互相通信,改宿主机端口不影响容器内部连接。

docker-compose.yml ​

项目根目录的 docker-compose.yml 内容如下(供参考,无需手动创建):

yaml
# =============================================================================
# Docker Compose — RXThinkCMF Laravel13 容器编排
# =============================================================================
# 架构: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
# =============================================================================

services:

  # ===========================================================================
  # Nginx 反向代理
  # ===========================================================================
  nginx:
    image: nginx:1.25-alpine
    container_name: rxthinkcmf-laravel13-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-laravel13-net
    restart: unless-stopped

  # ===========================================================================
  # PHP-FPM 应用服务
  # ===========================================================================
  # 执行 Laravel 代码,处理 API 请求和业务逻辑
  # ===========================================================================
  app:
    build:
      context: .                         # 构建上下文为项目根目录
      dockerfile: docker/Dockerfile      # Dockerfile 路径
    container_name: rxthinkcmf-laravel13-app
    volumes:
      - ./:/var/www/html                                          # 项目代码(可写,上传文件随宿主机持久化)
    environment:
      - APP_DEBUG=\${APP_DEBUG:-true}                              # 调试模式(快速体验默认开启)

      # 数据库:容器内通过服务名 mysql 访问(覆盖 .env 中的 127.0.0.1)
      - DB_CONNECTION=mysql
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_DATABASE=\${MYSQL_DATABASE:-rxthinkcmf.laravel13.naivevue}
      - DB_USERNAME=root
      - DB_PASSWORD=\${MYSQL_ROOT_PASSWORD:-root123}

      # 缓存 / 会话 / 队列:统一走 Redis(数据库脚本不含 framework 表)
      - CACHE_STORE=redis
      - SESSION_DRIVER=redis
      - QUEUE_CONNECTION=redis
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=\${REDIS_PASSWORD:-redis123}

      # JWT 签名密钥(应用启动要求 >= 32 字符)
      - JWT_SECRET=\${JWT_SECRET:-your_random_jwt_secret_key_at_least_32_bytes_long}

      # 文件访问域名(接口返回上传文件的完整地址)
      - FILE_DOMAIN_URL=\${DOMAIN_URL:-http://admin.laravel13.naivevue}

      # 跨域来源(快速体验默认放开)
      - CORS_ALLOW_ORIGIN=\${CORS_ALLOW_ORIGIN:-*}

    depends_on:
      mysql:
        condition: service_healthy                # 等待 MySQL 就绪(含首次 SQL 导入)
      redis:
        condition: service_started                # 等待 Redis 启动
    networks:
      - rxthinkcmf-laravel13-net
    restart: unless-stopped

  # ===========================================================================
  # MySQL 数据库
  # ===========================================================================
  # 存储业务数据,首次启动自动导入数据库脚本
  # ===========================================================================
  mysql:
    image: mysql:8.0
    container_name: rxthinkcmf-laravel13-mysql
    ports:
      - "\${MYSQL_PORT:-3306}:3306"       # 宿主机端口(默认 3306),可通过环境变量覆盖
    environment:
      MYSQL_ROOT_PASSWORD: \${MYSQL_ROOT_PASSWORD:-root123}             # root 密码
      MYSQL_DATABASE: \${MYSQL_DATABASE:-rxthinkcmf.laravel13.naivevue}   # 自动创建的数据库
    volumes:
      - mysql_data:/var/lib/mysql                                     # 数据持久化
      - ./document/mysql/rxthinkcmf.laravel13.naivevue.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:-root123}"]
      interval: 10s
      timeout: 5s
      retries: 30
      start_period: 60s                  # 首次启动需导入约 226MB SQL,给足缓冲时间
    networks:
      - rxthinkcmf-laravel13-net
    restart: unless-stopped

  # ===========================================================================
  # Redis 缓存
  # ===========================================================================
  # 提供缓存加速(JWT 会话/字典/权限缓存),与 config/database.php 中 redis 配合
  # ===========================================================================
  redis:
    image: redis:7-alpine
    container_name: rxthinkcmf-laravel13-redis
    ports:
      - "\${REDIS_PORT:-6379}:6379"       # 宿主机端口(默认 6379),可通过环境变量覆盖
    command: redis-server --requirepass \${REDIS_PASSWORD:-redis123}  # 访问密码
    volumes:
      - redis_data:/data                                            # 数据持久化
    networks:
      - rxthinkcmf-laravel13-net
    restart: unless-stopped

# =============================================================================
# 命名卷 — 持久化存储
# =============================================================================
# 容器删除后数据保留,彻底重置请执行:docker compose down -v
# =============================================================================
volumes:
  mysql_data:       # MySQL 数据文件
  redis_data:       # Redis RDB 快照

# =============================================================================
# 内部网络
# =============================================================================
# 容器间通过服务名(mysql / redis / app)互相访问
# =============================================================================
networks:
  rxthinkcmf-laravel13-net:
    driver: bridge

Dockerfile ​

将以下内容保存为 docker/Dockerfile:

dockerfile
# =============================================================================
# Dockerfile — PHP-FPM 应用镜像(RXThinkCMF Laravel13)
# =============================================================================
# 基础镜像:PHP 8.3 + FPM(FastCGI 进程管理器)
# 构建命令:docker compose build app
# 运行方式:由 Nginx 容器通过 FastCGI 协议调用本容器的 9000 端口
# =============================================================================

FROM php:8.3-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 \\                     # Composer 解压依赖包
    && rm -rf /var/lib/apt/lists/*  # 清理 apt 缓存,减小镜像体积

# -----------------------------------------------------------------------------
# 2. 安装 PHP 扩展
# -----------------------------------------------------------------------------
# 项目必需扩展(根据 composer.json 和 config/ 推导):
#   pdo_mysql  — MySQL 数据库驱动(config/database.php 使用)
#   mbstring   — 多字节字符串处理(Laravel 框架依赖)
#   gd         — 图片处理(验证码生成、图片缩放)
#   bcmath     — 高精度数学运算(phpspreadsheet 依赖)
#   zip        — ZIP 压缩(phpspreadsheet 读写 xlsx 依赖)
#   redis      — Redis 扩展(phpredis:缓存/会话/队列/JWT 会话均依赖)
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"

RUN echo '\\n\\
; ====== 生产环境追加配置(Docker 自动生成) ====== \\n\\
\\n\\
display_errors = Off\\n\\
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED\\n\\
memory_limit = 256M\\n\\
max_execution_time = 60\\n\\
max_input_time = 60\\n\\
upload_max_filesize = 50M\\n\\
post_max_size = 50M\\n\\
max_file_uploads = 20\\n\\
date.timezone = Asia/Shanghai\\n\\
opcache.enable = 1\\n\\
opcache.memory_consumption = 256\\n\\
opcache.interned_strings_buffer = 16\\n\\
opcache.max_accelerated_files = 10000\\n\\
opcache.validate_timestamps = 1\\n\\
opcache.revalidate_freq = 0\\n\\
opcache.save_comments = 1\\n\\
' >> "$PHP_INI_DIR/php.ini"

# -----------------------------------------------------------------------------
# 5. 设置工作目录
# -----------------------------------------------------------------------------
WORKDIR /var/www/html

# -----------------------------------------------------------------------------
# 6. 复制项目文件并安装依赖(利用 Docker 层缓存)
# -----------------------------------------------------------------------------
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-interaction
COPY . .

# -----------------------------------------------------------------------------
# 7. 设置 Laravel 可写目录权限
# -----------------------------------------------------------------------------
# storage         — 日志、缓存、会话、编译视图(必须可写)
# bootstrap/cache — 配置/路由/事件缓存(必须可写)
# public/uploads  — 用户上传文件目录(必须可写)
RUN mkdir -p \\
        storage/framework/cache \\
        storage/framework/sessions \\
        storage/framework/views \\
        storage/logs \\
        bootstrap/cache \\
        public/uploads \\
    && chown -R www-data:www-data storage bootstrap/cache public/uploads \\
    && chmod -R 775 storage bootstrap/cache public/uploads

# -----------------------------------------------------------------------------
# 8. 暴露端口并启动
# -----------------------------------------------------------------------------
EXPOSE 9000
CMD ["php-fpm"]

Nginx 配置 ​

将以下内容保存为 docker/nginx.conf:

nginx
# =============================================================================
# Nginx 配置 — RXThinkCMF Laravel13 反向代理
# =============================================================================

server {
    # 监听容器内 80 端口(宿主机通过 docker-compose ports 映射到 8000)
    listen 80;
    server_name localhost;

    # 网站根目录指向 Laravel 公开目录(容器内代码挂载在 /var/www/html)
    root /var/www/html/public;
    index index.php;

    # -----------------------------------------------------------------
    # URL 重写(Laravel 路由)
    # -----------------------------------------------------------------
    # 真实文件直接返回,其余交给 public/index.php 由 Laravel 路由解析
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # -----------------------------------------------------------------
    # PHP-FPM 处理(仅入口 index.php 可执行)
    # -----------------------------------------------------------------
    # "app" 是 docker-compose 中 PHP-FPM 服务的名称,Docker 内部 DNS 自动解析
    location = /index.php {
        fastcgi_pass   app:9000;            # 转发到 PHP-FPM 容器的 9000 端口
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;       # 引入标准 FastCGI 参数
        fastcgi_read_timeout  300;           # 超时设置(秒),防止长请求被提前断开
        fastcgi_send_timeout  300;
    }

    # 其余 .php 文件(含上传目录)一律 404,防止恶意脚本被执行
    location ~ \\.php$ {
        return 404;
    }

    # -----------------------------------------------------------------
    # 安全规则:禁止访问隐藏文件(如 .env、.git、.htaccess)
    # -----------------------------------------------------------------
    location ~ /\\. {
        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 application/xml;
    gzip_min_length 1024;
    gzip_comp_level 5;
}

环境变量配置 ​

将以下内容保存为 docker/.env.docker:

ini
# Docker 环境变量(密码等敏感信息,切勿提交 Git)

# 端口(宿主机端口,冲突时修改)
NGINX_PORT=8000
MYSQL_PORT=3306
REDIS_PORT=6379

# MySQL(首次启动自动导入 document/mysql/rxthinkcmf.laravel13.naivevue.sql)
MYSQL_ROOT_PASSWORD=Your_Strong_Password_2024
MYSQL_DATABASE=rxthinkcmf.laravel13.naivevue

# Redis
REDIS_PASSWORD=Your_Redis_Password_2024

# 应用
JWT_SECRET=<32 字符以上随机值,openssl rand -base64 32 生成>
APP_DEBUG=false
DOMAIN_URL=http://admin.laravel13.naivevue
CORS_ALLOW_ORIGIN=http://admin.laravel13.naivevue

与本地 .env 的关系

docker-compose.yml 的 environment 块会把数据库 / Redis / JWT 等配置以容器环境变量注入,优先级高于 .env 文件——因此容器内自动使用服务名 mysql / redis,无需修改本地 .env(与手动部署用同一份 .env 互不干扰)。

配置优先级 ​

变量插值优先级(高 → 低):

text
1. shell 环境变量
2. --env-file 指定的文件(如 docker/.env.docker)
3. 项目根目录 .env(compose 自动读取)
4. docker-compose.yml 中的 \${VAR:-默认值}

访问服务 ​

启动成功后:

服务地址说明
后端 APIhttp://admin.laravel13.naivevueNginx → PHP-FPM → Laravel
健康检查http://admin.laravel13.naivevue/upLaravel 内置健康路由
MySQLlocalhost:3306用户名 root,默认密码 root123
Redislocalhost:6379默认密码 redis123

验证后端是否正常:

bash
# 健康检查
curl http://admin.laravel13.naivevue/up

# 验证码(同时验证 PHP→Redis 链路,返回 code=0 即成功)
curl http://admin.laravel13.naivevue/api/captcha
# → {"code":0,"ok":true,"msg":"操作成功","data":{...}}

# 登录获取 Token(默认管理员账号 admin / 123456,登录后立即修改)
# 验证码参数 key/code 与 /api/captcha 响应字段一致
curl -X POST http://admin.laravel13.naivevue/api/login \\
  -H "Content-Type: application/json" \\
  -d '{"username":"admin","password":"123456","key":"<captcha_key>","code":"<验证码字符>"}'

数据持久化 ​

数据位置down 后down -v 后
MySQL 数据命名卷 mysql_data保留删除
Redis 数据命名卷 redis_data保留删除
上传文件宿主机项目目录(挂载)保留保留
代码宿主机项目目录(挂载)保留保留

常用命令 ​

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
docker compose logs -f mysql

# --------------------------------------------------------------------------
# 进入容器
# --------------------------------------------------------------------------
# 进入 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.laravel13.naivevue < document/mysql/rxthinkcmf.laravel13.naivevue.sql

# 进入 MySQL 命令行
docker compose exec mysql mysql -uroot -pYour_Strong_Password_2024 rxthinkcmf.laravel13.naivevue

# --------------------------------------------------------------------------
# Laravel Artisan 命令
# --------------------------------------------------------------------------
# 清除配置缓存
docker compose exec app php artisan config:clear

# 容器内执行 tinker 验证 Redis 连通
docker compose exec app php artisan tinker

# 查看路由列表
docker compose exec app php artisan route:list

常见问题 ​

端口被占用 ​

bash
# Windows 查看占用端口的进程
netstat -ano | findstr :8000

# Linux/Mac
lsof -i :8000

# 解决方案:修改 docker/.env.docker 中的端口
# NGINX_PORT=8080    # 改为 8080

数据库连接失败 ​

docker-compose.yml 的 environment 块会把 DB_HOST 覆盖为 mysql(Docker 服务名)。若手动改过 compose 导致覆盖失效,确认容器内环境变量 DB_HOST=mysql,不是 127.0.0.1:

bash
docker compose exec app printenv DB_HOST
# → mysql

容器启动后立即退出 ​

bash
# 查看退出原因
docker compose logs app

# 常见原因:
# 1. JWT_SECRET 长度不足(< 32 字符)→ 应用 fail-close 拒绝启动,重新生成密钥
# 2. PHP 扩展缺失 → 检查 Dockerfile 中的 docker-php-ext-install
# 3. 目录权限问题 → 确认 storage 和 bootstrap/cache 目录可写
# 4. composer install 失败 → 检查网络或镜像源

首次启动 mysql 一直 unhealthy ​

首次启动需导入约 226MB 数据库脚本,初始化 1~3 分钟属正常。查看进度:

bash
docker compose logs -f mysql
# 等待 "ready for connections" 出现后,mysql 变为 healthy,app 自动启动

验证码一直失败 ​

Redis 未启动或密码不匹配:

bash
docker compose ps                 # 确认 redis 容器状态
docker compose logs redis         # 查看 Redis 日志
docker compose exec app php artisan tinker   # 容器内验证连通

重新开始 ​

bash
# 删除所有容器、网络、数据卷,完全重来
docker compose down -v
docker compose up -d --build

相关文档 ​

`,62)])])}const g=i(p,[["render",h]]);export{E as __pageData,g as default};