467 lines
118 KiB
JavaScript
467 lines
118 KiB
JavaScript
import{_ as i,o as a,c as n,a2 as l}from"./chunks/framework.BbmSSMjL.js";const c=JSON.parse('{"title":"11.6 Docker 生产部署","description":"","frontmatter":{},"headers":[],"relativePath":"zh/deploy/docker.md","filePath":"zh/deploy/docker.md"}'),p={name:"zh/deploy/docker.md"};function h(k,s,t,e,d,r){return a(),n("div",null,[...s[0]||(s[0]=[l(`<h1 id="_11-6-Docker-生产部署" tabindex="-1">11.6 Docker 生产部署 <a class="header-anchor" href="#_11-6-Docker-生产部署" aria-label="Permalink to "11.6 Docker 生产部署""></a></h1><div class="tip custom-block"><p class="custom-block-title">概述</p><p>本节提供基于 Docker Compose 的生产环境部署方案,包含 <strong>Nginx 反向代理</strong>、<strong>PHP-FPM 应用</strong>、<strong>MySQL 数据库</strong>和 <strong>Redis 缓存</strong>四个服务的容器编排配置。所有脚本均带详细注释,适合快速搭建生产环境,也便于 CI/CD 集成。本地快速体验请先阅读 <a href="/zh/quickstart/docker.html">2.8 Docker 快速体验</a>。</p></div><h2 id="架构说明" tabindex="-1">架构说明 <a class="header-anchor" href="#架构说明" aria-label="Permalink to "架构说明""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>浏览器 → 宿主机:8000 → [Nginx 容器:80] → [PHP-FPM 容器:9000] → Laravel 应用</span></span>
|
||
<span class="line"><span> ↕</span></span>
|
||
<span class="line"><span> [MySQL 容器:3306] + [Redis 容器:6379]</span></span></code></pre></div><ul><li><strong>Nginx</strong>:监听 80 端口,处理 HTTP 请求、URL 重写、静态资源缓存</li><li><strong>PHP-FPM</strong>:监听 9000 端口,执行 PHP 代码</li><li><strong>MySQL</strong>:数据库服务,数据持久化到 Docker 命名卷</li><li><strong>Redis</strong>:缓存 / 会话 / 队列服务,数据持久化到 Docker 命名卷</li></ul><h2 id="与快速体验的差异" tabindex="-1">与快速体验的差异 <a class="header-anchor" href="#与快速体验的差异" aria-label="Permalink to "与快速体验的差异""></a></h2><table tabindex="0"><thead><tr><th>项</th><th>2.8 快速体验</th><th>本节生产部署</th></tr></thead><tbody><tr><td>启动命令</td><td><code>docker compose up -d</code></td><td><code>docker compose --env-file docker/.env.docker up -d --build</code></td></tr><tr><td>密码</td><td>compose 内置默认值(root123 / redis123)</td><td><code>.env.docker</code> 中的强密码</td></tr><tr><td><code>APP_DEBUG</code></td><td><code>true</code></td><td><strong><code>false</code></strong></td></tr><tr><td><code>JWT_SECRET</code></td><td>占位值或 <code>.env</code> 值</td><td><code>openssl rand -base64 32</code> 生成的随机值</td></tr><tr><td><code>CORS_ALLOW_ORIGIN</code></td><td><code>*</code></td><td>前端站点具体域名</td></tr><tr><td>数据库 / Redis 端口</td><td>映射到宿主机</td><td><strong>建议注释掉映射或绑定 127.0.0.1</strong></td></tr><tr><td>OPcache</td><td><code>validate_timestamps=1</code></td><td>建议改为 <code>0</code>(见「性能调优」)</td></tr></tbody></table><h2 id="前置要求" tabindex="-1">前置要求 <a class="header-anchor" href="#前置要求" aria-label="Permalink to "前置要求""></a></h2><table tabindex="0"><thead><tr><th>依赖</th><th>版本要求</th><th>说明</th></tr></thead><tbody><tr><td>Docker</td><td>>= 20.10</td><td>容器运行时</td></tr><tr><td>Docker Compose</td><td>>= 2.0</td><td>容器编排工具</td></tr><tr><td>磁盘空间</td><td>>= 5GB</td><td>镜像 + 数据卷</td></tr><tr><td>服务器</td><td>2 核 / 4 GB 起</td><td>数据库初始化导入约 226MB</td></tr></tbody></table><h2 id="部署-Checklist" tabindex="-1">部署 Checklist <a class="header-anchor" href="#部署-Checklist" aria-label="Permalink to "部署 Checklist""></a></h2><table tabindex="0"><thead><tr><th>#</th><th>步骤</th><th>说明</th></tr></thead><tbody><tr><td>1</td><td>服务器安装 Docker</td><td><code>docker compose version</code> 验证</td></tr><tr><td>2</td><td>获取代码</td><td><code>git clone</code> 或上传代码包</td></tr><tr><td>3</td><td>初始化 <code>.env</code></td><td><code>composer setup</code> 或 <code>cp .env.example .env</code> + <code>key:generate</code>(容器外执行)</td></tr><tr><td>4</td><td>定制 <code>docker/.env.docker</code></td><td>强密码、随机 JWT_SECRET、生产域名(见「环境变量配置」)</td></tr><tr><td>5</td><td>端口映射调整</td><td>数据库 / Redis 端口注释掉或绑定 <code>127.0.0.1</code></td></tr><tr><td>6</td><td>构建并启动</td><td><code>docker compose --env-file docker/.env.docker up -d --build</code></td></tr><tr><td>7</td><td>验证</td><td><code>/up</code> 健康检查、<code>/api/captcha</code> 返回 <code>code=0</code></td></tr><tr><td>8</td><td>前端部署</td><td>见 <a href="/zh/deploy/frontend.html">11.5 前端部署</a></td></tr><tr><td>9</td><td>监控与备份</td><td><code>/up</code> 挂监控、数据库定时备份,见 <a href="/zh/deploy/backup.html">11.9 备份与恢复</a></td></tr></tbody></table><h2 id="文件结构" tabindex="-1">文件结构 <a class="header-anchor" href="#文件结构" aria-label="Permalink to "文件结构""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>RXThinkCMF_Laravel13_NaiveVue/</span></span>
|
||
<span class="line"><span>├── docker/</span></span>
|
||
<span class="line"><span>│ ├── Dockerfile # PHP-FPM 应用镜像定义</span></span>
|
||
<span class="line"><span>│ ├── nginx.conf # Nginx 站点配置</span></span>
|
||
<span class="line"><span>│ └── .env.docker # Docker 环境变量(密码等敏感信息)</span></span>
|
||
<span class="line"><span>├── docker-compose.yml # 容器编排配置(放在项目根目录)</span></span>
|
||
<span class="line"><span>├── .dockerignore # 构建上下文排除(.env、vendor、SQL 等)</span></span>
|
||
<span class="line"><span>├── .env # 应用配置(Laravel 读取)</span></span>
|
||
<span class="line"><span>└── ...</span></span></code></pre></div><h2 id="Dockerfile" tabindex="-1">Dockerfile <a class="header-anchor" href="#Dockerfile" aria-label="Permalink to "Dockerfile""></a></h2><div class="language-dockerfile vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">dockerfile</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Dockerfile — PHP-FPM 应用镜像(RXThinkCMF Laravel13)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 基础镜像:PHP 8.3 + FPM(FastCGI 进程管理器)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 构建命令:docker compose build app</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 运行方式:由 Nginx 容器通过 FastCGI 协议调用本容器的 9000 端口</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">FROM</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> php:8.3-fpm</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 1. 安装系统依赖</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># PHP 扩展编译需要的 C 库和工具,安装后清理 apt 缓存减小镜像体积</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> apt-get update && apt-get install -y --no-install-recommends \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> libpng-dev </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # GD 扩展 — PNG 支持</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> libjpeg-dev </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # GD 扩展 — JPEG 支持</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> libfreetype6-dev </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # GD 扩展 — 字体渲染(验证码依赖)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> libzip-dev </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # zip 扩展依赖</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> zip </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # Composer 安装依赖包时可能用到</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> unzip </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> # Composer 解压依赖包</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && rm -rf /var/lib/apt/lists/* # 清理 apt 缓存,减小镜像体积</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 2. 安装 PHP 扩展</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 项目必需扩展(根据 composer.json 和 config/ 推导):</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># pdo_mysql — MySQL 数据库驱动(config/database.php 使用)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># mbstring — 多字节字符串处理(Laravel 框架依赖,composer 平台检查)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># gd — 图片处理(验证码生成、图片缩放)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># bcmath — 高精度数学运算(phpspreadsheet 依赖)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># zip — ZIP 压缩(phpspreadsheet 读写 xlsx 依赖)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># redis — Redis 扩展(phpredis:缓存/会话/队列/JWT 会话均依赖)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> docker-php-ext-configure gd --with-freetype --with-jpeg \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && docker-php-ext-install -j$(nproc) \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> pdo_mysql \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> mbstring \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> gd \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> bcmath \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> zip \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && pecl install redis \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && docker-php-ext-enable redis</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 3. 安装 Composer</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 从官方镜像复制 composer 二进制文件,避免重复安装</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">COPY</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> --from=composer:latest /usr/bin/composer /usr/bin/composer</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 4. 配置 PHP 生产环境参数</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 使用 php.ini-production 作为基础,追加项目所需配置</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> mv </span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">"$PHP_INI_DIR/php.ini-production"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> "$PHP_INI_DIR/php.ini"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 生产环境追加配置:内存、超时、上传、时区、OPcache 等</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> echo </span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">'</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; ====== 生产环境追加配置(Docker 自动生成) ====== </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; 关闭错误显示,防止敏感信息泄露到前端</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">display_errors = Off</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; 内存与超时</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">memory_limit = 256M</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">max_execution_time = 60</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">max_input_time = 60</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; 文件上传(与 .env 中 FILE_MAX_SIZE 配合)</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">upload_max_filesize = 50M</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">post_max_size = 50M</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">max_file_uploads = 20</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; 时区(与应用时区一致)</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">date.timezone = Asia/Shanghai</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; OPcache 加速</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; validate_timestamps=1 + revalidate_freq=0:挂载宿主机代码即时生效(开发友好)</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">; 生产环境建议改为 validate_timestamps=0(见 11.6「性能调优」)</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.enable = 1</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.memory_consumption = 256</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.interned_strings_buffer = 16</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.max_accelerated_files = 10000</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.validate_timestamps = 1</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.revalidate_freq = 0</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">opcache.save_comments = 1</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">\\n</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">\\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> >> </span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">"$PHP_INI_DIR/php.ini"</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 5. 设置工作目录</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">WORKDIR</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> /var/www/html</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 6. 复制项目文件并安装依赖</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 先复制 composer 文件,利用 Docker 层缓存 ——</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 只要 composer.json / composer.lock 没变就不重新安装依赖</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">COPY</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> composer.json composer.lock ./</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> composer install --no-dev --optimize-autoloader --no-interaction</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 再复制全部项目文件(.env、vendor、node_modules 已被 .dockerignore 排除)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">COPY</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> . .</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 7. 设置 Laravel 可写目录权限</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># storage — 日志、缓存、会话、编译视图(必须可写)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># bootstrap/cache — 配置/路由/事件缓存(必须可写)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># public/uploads — 用户上传文件目录(必须可写)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RUN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> mkdir -p \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> storage/framework/cache \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> storage/framework/sessions \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> storage/framework/views \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> storage/logs \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> bootstrap/cache \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> public/uploads \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && chown -R www-data:www-data storage bootstrap/cache public/uploads \\</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> && chmod -R 775 storage bootstrap/cache public/uploads</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 8. 暴露端口并启动</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># -----------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 9000 是 PHP-FPM 的 FastCGI 监听端口,Nginx 通过此端口转发请求</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">EXPOSE</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> 9000</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">CMD</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> [</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">"php-fpm"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">]</span></span></code></pre></div><h2 id="Nginx-配置" tabindex="-1">Nginx 配置 <a class="header-anchor" href="#Nginx-配置" aria-label="Permalink to "Nginx 配置""></a></h2><div class="language-nginx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">nginx</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Nginx 配置 — RXThinkCMF Laravel13 反向代理</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 用途:Docker 容器内 Nginx 服务,将 HTTP 请求转发给 PHP-FPM 处理</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 挂载方式:docker-compose 中 volumes 映射到 /etc/nginx/conf.d/default.conf</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">server</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 监听容器内 80 端口(宿主机通过 docker-compose ports 映射到 8000)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> listen </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">80</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> server_name </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">localhost</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 网站根目录指向 Laravel 公开目录</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 容器内代码挂载在 /var/www/html,入口文件在 public/index.php</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> root </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/var/www/html/public</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> index </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">index.php</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # URL 重写(Laravel 路由)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 真实存在的文件/目录直接返回,其余请求全部交给 public/index.php,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 由 Laravel 路由解析(如 /api/user/page → index.php 处理)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> location</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#59873A;"> / </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> try_files </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">uri</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">uri</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/ /index.php?</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">query_string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # PHP-FPM 处理(仅入口 index.php 可执行)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # "app" 是 docker-compose 中 PHP-FPM 服务的名称,Docker 内部 DNS 自动解析</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> location</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> =</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;"> /index.php </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> fastcgi_pass </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> app:9000</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 转发到 PHP-FPM 容器的 9000 端口</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> fastcgi_index </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> index.php</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 默认索引文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> fastcgi_param </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> SCRIPT_FILENAME </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">document_root</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">fastcgi_script_name</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> include </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> fastcgi_params</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 引入标准 FastCGI 参数</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 超时设置(秒),防止长请求被 Nginx 提前断开</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> fastcgi_read_timeout </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 300</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> fastcgi_send_timeout </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 300</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 其余 .php 文件(含上传目录、storage 目录)一律 404</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 防止恶意文件上传后被执行 —— 只有入口 index.php 能够运行</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> location</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ~</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;"> \\.php$ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 404</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 安全规则:禁止访问隐藏文件(如 .env、.git、.htaccess)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> location</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ~</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;"> /\\. </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> deny </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;">all</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 静态资源缓存</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 常见静态文件类型设置 30 天浏览器缓存,减少重复请求</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> location</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ~*</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;"> \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> expires </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">30d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> add_header </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">Cache-Control </span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">"public, immutable"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Gzip 压缩</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # -----------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> gzip </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;"> on</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> gzip_types </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> text/plain text/css application/json application/javascript text/xml application/xml</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> gzip_min_length </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">1024</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 小于 1KB 的响应不压缩(压缩收益低)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> gzip_comp_level </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">5</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 压缩级别 1-9,5 为性能与压缩率的平衡点</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">}</span></span></code></pre></div><h2 id="docker-compose-yml" tabindex="-1">docker-compose.yml <a class="header-anchor" href="#docker-compose-yml" aria-label="Permalink to "docker-compose.yml""></a></h2><div class="tip custom-block"><p class="custom-block-title">与实际文件的关系</p><p>项目根目录已内置 <code>docker-compose.yml</code>,支持两种模式:</p><ul><li><strong>快速体验</strong>:<code>docker compose up -d</code>(使用默认密码 root123 / redis123)</li><li><strong>生产部署</strong>:<code>docker compose --env-file docker/.env.docker up -d --build</code>(使用生产密码)</li></ul><p>下方为生产推荐配置参考,实际文件通过 <code>\${VAR:-默认值}</code> 语法兼容两种场景。</p></div><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Docker Compose 生产部署配置(RXThinkCMF Laravel13)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 服务架构:Nginx → PHP-FPM → MySQL + Redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 启动命令:docker compose --env-file docker/.env.docker up -d</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 停止命令:docker compose down</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">services</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Nginx 反向代理服务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 职责:接收外部 HTTP 请求,转发 index.php 到 PHP-FPM,直接返回静态资源</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 端口:容器内 80 → 宿主机 8000</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> nginx</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> image</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> nginx:1.25-alpine</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 官方 Nginx 镜像(Alpine 版本,体积小)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> container_name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-nginx</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> ports</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">8000:80</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 宿主机 8000 → 容器 80</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 站点配置</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./:/var/www/html:ro</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 项目代码(只读,与 PHP-FPM 共享同一份)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> depends_on</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 确保 PHP-FPM 先启动</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> networks</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-net</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> restart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> unless-stopped</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 异常退出自动重启</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # PHP-FPM 应用服务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 职责:执行 Laravel PHP 代码,处理业务逻辑</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 端口:9000(FastCGI 协议,仅 Nginx 内部访问,不映射宿主机)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> app</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> build</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> context</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> .</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 构建上下文为项目根目录</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> dockerfile</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/Dockerfile</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> container_name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-app</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./:/var/www/html</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 挂载项目代码(更新时无需重建镜像)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> environment</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> APP_DEBUG=\${APP_DEBUG:-false}</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 调试模式,默认关闭</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据库:容器内通过服务名 mysql 访问</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_CONNECTION=mysql</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_HOST=mysql</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_PORT=3306</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_DATABASE=\${MYSQL_DATABASE:-rxthinkcmf.laravel13.naivevue}</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_USERNAME=root</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> DB_PASSWORD=\${MYSQL_ROOT_PASSWORD}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 缓存 / 会话 / 队列:统一走 Redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> CACHE_STORE=redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> SESSION_DRIVER=redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> QUEUE_CONNECTION=redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> REDIS_HOST=redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> REDIS_PORT=6379</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> REDIS_PASSWORD=\${REDIS_PASSWORD}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # JWT 密钥 / 文件域名 / 跨域(取自 --env-file)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> JWT_SECRET=\${JWT_SECRET}</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> FILE_DOMAIN_URL=\${DOMAIN_URL:-http://admin.laravel13.naivevue}</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> CORS_ALLOW_ORIGIN=\${CORS_ALLOW_ORIGIN:-*}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> depends_on</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> mysql</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> condition</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> service_healthy</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 确保数据库就绪(含首次 SQL 导入)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> redis</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> condition</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> service_started</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> networks</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-net</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> restart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> unless-stopped</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # MySQL 数据库服务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 职责:存储业务数据(用户、菜单、字典、文章等)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> mysql</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> image</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql:8.0</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # MySQL 8.0 官方镜像</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> container_name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-mysql</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ports: # 生产环境建议注释掉,不暴露到宿主机</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # - "3306:3306"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> environment</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> MYSQL_ROOT_PASSWORD</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> \${MYSQL_ROOT_PASSWORD}</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # root 用户密码(>=16 位强密码)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> MYSQL_DATABASE</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> \${MYSQL_DATABASE:-rxthinkcmf.laravel13.naivevue}</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql_data:/var/lib/mysql</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据持久化</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 初始化 SQL(首次启动自动执行,仅在数据卷为空时生效)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./document/mysql/rxthinkcmf.laravel13.naivevue.sql:/docker-entrypoint-initdb.d/init.sql:ro</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> command</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> --character-set-server=utf8mb4</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> --collation-server=utf8mb4_general_ci</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> --default-authentication-plugin=mysql_native_password</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> healthcheck</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> test</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">CMD</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">mysqladmin</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">ping</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">-h</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">localhost</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">-u</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">root</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">-p\${MYSQL_ROOT_PASSWORD}</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> interval</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 10s</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> timeout</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 5s</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> retries</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 30</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> start_period</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 60s</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 首次导入约 226MB SQL,给足缓冲</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> networks</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-net</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> restart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> unless-stopped</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Redis 缓存服务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 职责:JWT 会话、字典/权限缓存、队列(config/database.php redis 配置)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ===========================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> redis</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> image</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> redis:7-alpine</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Redis 7 Alpine 版本(体积小)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> container_name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-redis</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ports: # 生产环境建议注释掉,不暴露到宿主机</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # - "6379:6379"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> command</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> redis-server --requirepass \${REDIS_PASSWORD}</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 设置访问密码</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> redis_data:/data</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据持久化(RDB 快照)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> networks</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13-net</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> restart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> unless-stopped</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 命名卷(Named Volumes)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Docker 管理的持久化存储,容器删除后数据保留</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 删除所有数据:docker compose down -v(-v 参数同时删除命名卷)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> mysql_data</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # MySQL 数据文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> redis_data</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Redis RDB 快照文件</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 内部网络</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 所有服务通过此网络互通,容器间使用服务名(如 "mysql")作为主机名</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 外部无法直接访问此网络,必须通过 Nginx 的 ports 映射进入</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># =============================================================================</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">networks</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> rxthinkcmf-laravel13-net</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> driver</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> bridge</span></span></code></pre></div><h2 id="环境变量配置" tabindex="-1">环境变量配置 <a class="header-anchor" href="#环境变量配置" aria-label="Permalink to "环境变量配置""></a></h2><p>创建 / 编辑 <code>docker/.env.docker</code> 文件:</p><div class="language-ini vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ini</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Docker 环境变量(密码等敏感信息,切勿提交 Git)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 端口(宿主机端口)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">NGINX_PORT</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">8000</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">MYSQL_PORT</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">3306</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">REDIS_PORT</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">6379</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># MySQL(首次启动自动导入数据库脚本)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">MYSQL_ROOT_PASSWORD</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"><16 位以上强密码></span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">MYSQL_DATABASE</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">rxthinkcmf.laravel13.naivevue</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Redis(与数据库密码不同)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">REDIS_PASSWORD</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"><强密码></span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 应用</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">JWT_SECRET</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"><openssl rand -base64 32 生成,>= 32 字符></span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">APP_DEBUG</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">false</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">DOMAIN_URL</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">https://admin.example.com</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">CORS_ALLOW_ORIGIN</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">https://www.example.com</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">安全提示</p><ul><li><code>docker/.env.docker</code> 包含生产密码,<strong>必须加入 <code>.gitignore</code>,切勿提交到 Git 仓库</strong></li><li>密码至少 16 位,包含大小写字母和数字,MySQL 与 Redis 密码不同</li><li><code>JWT_SECRET</code> 是令牌签名根密钥,泄露等于任意用户令牌可伪造;不同环境使用不同密钥</li></ul></div><h2 id="应用-env-配置" tabindex="-1">应用 .env 配置 <a class="header-anchor" href="#应用-env-配置" aria-label="Permalink to "应用 .env 配置""></a></h2><p>容器启动前,确保项目根目录 <code>.env</code> 已初始化(<code>APP_KEY</code>、<code>JWT_SECRET</code>、<code>DB_PREFIX</code>):</p><div class="language-ini vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ini</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">APP_KEY</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 留空,composer setup 的 key:generate 生成</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">JWT_SECRET</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"><32 字符以上随机值> </span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 应用启动 fail-close 校验</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">DB_PREFIX</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">laravel_ </span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 数据库脚本使用 laravel_ 前缀,必须保留</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">数据库连接无需修改</p><p><code>docker-compose.yml</code> 的 <code>environment</code> 块已把 <code>DB_HOST</code> 覆盖为 <code>mysql</code>、<code>REDIS_HOST</code> 覆盖为 <code>redis</code>(容器环境变量优先级高于 <code>.env</code> 文件),本地 <code>.env</code> 保持 <code>127.0.0.1</code> 即可与手动部署共用同一份配置。</p></div><h2 id="启动部署" tabindex="-1">启动部署 <a class="header-anchor" href="#启动部署" aria-label="Permalink to "启动部署""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 1. 配置环境变量</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 复制模板并修改密码</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">cp</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker.local</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">vi</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker.local</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 修改密码、JWT_SECRET、域名</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 2. 配置应用 .env</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">cp</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> .env.example</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> .env</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> key:generate</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 生成 APP_KEY</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 3. 构建并启动所有服务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --env-file</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker.local</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> up</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -d</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --build</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 4. 查看运行状态(首次 mysql 需导入约 226MB SQL,等 healthy)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ps</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 5. 查看应用日志(确认无报错)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> logs</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 6. 验证</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">curl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> https://your-domain/up</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">curl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> http://admin.laravel13.naivevue/api/captcha</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 返回 code=0 即成功</span></span></code></pre></div><h3 id="首次初始化与数据迁移" tabindex="-1">首次初始化与数据迁移 <a class="header-anchor" href="#首次初始化与数据迁移" aria-label="Permalink to "首次初始化与数据迁移""></a></h3><ul><li>MySQL 仅在<strong>数据卷为空</strong>时执行 <code>docker-entrypoint-initdb.d</code> 中的初始化 SQL;</li><li>已有数据卷不会重复导入,更换 SQL 脚本需先 <code>docker compose down -v</code>(<strong>会清空数据</strong>);</li><li>从旧环境迁入已有数据:</li></ul><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Linux / Git Bash</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -T</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> sh</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -c</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Windows CMD(PowerShell 不支持 < 重定向,用 cmd /c 包裹)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">cmd</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /c</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">docker compose exec -T mysql mysql -uroot -p<密码> rxthinkcmf.laravel13.naivevue < backup.sql</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span></code></pre></div><h2 id="日常运维" tabindex="-1">日常运维 <a class="header-anchor" href="#日常运维" aria-label="Permalink to "日常运维""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 代码更新</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">git</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> pull</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --env-file</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> build</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --env-file</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> up</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -d</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 生命周期管理</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> up</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -d</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 启动所有服务(后台运行)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> down</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 停止所有服务(保留数据卷)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> down</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -v</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 停止并删除所有数据卷(⚠️ 清空数据库)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> restart</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 重启单个服务(修改 .env 后生效)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 日志排查</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> logs</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 所有服务日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> logs</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 应用日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> logs</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> nginx</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # Nginx 日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> logs</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 数据库日志(首次看导入进度)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 进入容器调试</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> bash</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 进入 PHP-FPM 容器</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> bash</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 进入 MySQL 容器</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -uroot</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><密码></span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 数据库操作</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 导出数据库备份</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -T</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> sh</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -c</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">exec mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%Y%m%d</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 导入 SQL 文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -T</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -uroot</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -p</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><密码></span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># Laravel Artisan 命令</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># --------------------------------------------------------------------------</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> config:cache</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 缓存配置(生产建议)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> route:cache</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 缓存路由</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> migrate</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --force</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 执行迁移</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> config:clear</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 清除配置缓存</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> route:list</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 查看路由列表</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">定时任务</p><p>项目内置 Cron / Daemon 双模式定时任务(见 <a href="/zh/modules/job.html">6.11 定时任务</a>),容器化部署时在宿主机配置 Crontab 调用 <code>docker compose exec app php artisan ...</code>,或单独以 <code>app</code> 镜像运行常驻容器执行任务守护命令。</p></div><h2 id="性能调优" tabindex="-1">性能调优 <a class="header-anchor" href="#性能调优" aria-label="Permalink to "性能调优""></a></h2><h3 id="OPcache-生产建议-" tabindex="-1">OPcache(生产建议) <a class="header-anchor" href="#OPcache-生产建议-" aria-label="Permalink to "OPcache(生产建议)""></a></h3><p>镜像默认 <code>opcache.validate_timestamps=1</code>(便于挂载代码即时生效)。生产环境代码不再变动,建议在 <code>docker/Dockerfile</code> 中改为:</p><div class="language-ini vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ini</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">opcache.validate_timestamps</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> 0 </span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 代码不再重新检查,性能最优</span></span></code></pre></div><p>修改后重新构建镜像:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --env-file</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> build</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --env-file</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> docker/.env.docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> up</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -d</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p><code>validate_timestamps=0</code> 后修改代码必须重启容器(或重新构建)才会生效。</p></div><h3 id="PHP-FPM" tabindex="-1">PHP-FPM <a class="header-anchor" href="#PHP-FPM" aria-label="Permalink to "PHP-FPM""></a></h3><p>镜像使用 <code>php-fpm</code> 默认动态进程池。并发较高时按 CPU 核数调整 <code>www.conf</code> 的 <code>pm.max_children</code>(建议 <code>(内存 - 系统占用) / 单进程内存</code>),可通过自定义配置挂载覆盖。</p><h3 id="MySQL-Redis" tabindex="-1">MySQL / Redis <a class="header-anchor" href="#MySQL-Redis" aria-label="Permalink to "MySQL / Redis""></a></h3><ul><li>MySQL 数据在命名卷 <code>mysql_data</code>,大表查询配合项目索引策略(见 <a href="/zh/architecture/database-design.html">4.9 数据库设计</a>);</li><li>Redis 建议设置 <code>maxmemory</code> + 淘汰策略防止内存耗尽——注意 <strong>JWT 会话存储在 Redis</strong>,淘汰策略不当会导致用户掉线。</li></ul><h3 id="生产环境建议" tabindex="-1">生产环境建议 <a class="header-anchor" href="#生产环境建议" aria-label="Permalink to "生产环境建议""></a></h3><table tabindex="0"><thead><tr><th>配置项</th><th>建议值</th><th>说明</th></tr></thead><tbody><tr><td>APP_DEBUG</td><td>false</td><td>关闭调试模式,防止堆栈/路径泄露</td></tr><tr><td>MYSQL_ROOT_PASSWORD</td><td>强密码(>=16位)</td><td>包含大小写字母和数字</td></tr><tr><td>REDIS_PASSWORD</td><td>强密码</td><td>与数据库密码不同</td></tr><tr><td>JWT_SECRET</td><td>随机字符串(>=32字符)</td><td><code>openssl rand -base64 32</code></td></tr><tr><td>CORS_ALLOW_ORIGIN</td><td>前端具体域名</td><td>生产禁止 <code>*</code></td></tr><tr><td>数据库/Redis 端口</td><td>注释掉映射</td><td>容器间通信不需要宿主机映射</td></tr><tr><td>数据卷</td><td>持久化挂载</td><td>避免容器重启丢失数据</td></tr><tr><td>Nginx SSL</td><td>443 + 证书</td><td>生产环境必须启用 HTTPS</td></tr></tbody></table><h2 id="安全加固" tabindex="-1">安全加固 <a class="header-anchor" href="#安全加固" aria-label="Permalink to "安全加固""></a></h2><table tabindex="0"><thead><tr><th>项</th><th>措施</th></tr></thead><tbody><tr><td>调试模式</td><td><code>APP_DEBUG=false</code>(true 会泄露异常堆栈、配置信息)</td></tr><tr><td>JWT 密钥</td><td>随机生成、不同环境不同密钥、严格保密</td></tr><tr><td>数据库端口</td><td>注释 <code>docker-compose.yml</code> 中 mysql/redis 的 <code>ports</code> 映射,或绑定 <code>"127.0.0.1:3306:3306"</code></td></tr><tr><td>跨域</td><td><code>CORS_ALLOW_ORIGIN</code> 显式配置前端域名</td></tr><tr><td>敏感文件</td><td><code>.dockerignore</code> 已排除 <code>.env</code>、SQL 脚本;<code>nginx.conf</code> 禁止访问隐藏文件</td></tr><tr><td>PHP 执行</td><td>Nginx 仅允许入口 <code>index.php</code> 执行,上传目录中的 <code>.php</code> 一律 404</td></tr><tr><td>默认账号</td><td>首次登录后立即修改 <code>admin</code> 默认密码(见 <a href="/zh/modules/user.html">6.1 用户管理</a>)</td></tr></tbody></table><h2 id="SSL-配置-HTTPS-" tabindex="-1">SSL 配置(HTTPS) <a class="header-anchor" href="#SSL-配置-HTTPS-" aria-label="Permalink to "SSL 配置(HTTPS)""></a></h2><p>生产环境建议在 Nginx 前增加 SSL 终止,修改 <code>nginx.conf</code>:</p><div class="language-nginx vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">nginx</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">server</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> listen </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">443</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> ssl</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> server_name </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">api.example.com</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> ssl_certificate </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> /etc/nginx/ssl/cert.pem</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> ssl_certificate_key </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/etc/nginx/ssl/key.pem</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # ... 其余配置不变 ...</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># HTTP 跳转 HTTPS</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">server</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> listen </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">80</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> server_name </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">api.example.com</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 301</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> https://</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">server_name</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">request_uri</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">}</span></span></code></pre></div><p><code>docker-compose.yml</code> 中增加证书挂载:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">nginx</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> volumes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./ssl/cert.pem:/etc/nginx/ssl/cert.pem:ro</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> -</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> ./ssl/key.pem:/etc/nginx/ssl/key.pem:ro</span></span></code></pre></div><h2 id="备份与恢复" tabindex="-1">备份与恢复 <a class="header-anchor" href="#备份与恢复" aria-label="Permalink to "备份与恢复""></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 数据库备份(定时任务执行)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -T</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> sh</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -c</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">exec mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">date</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> +%F</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 数据库恢复</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -T</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> mysql</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> sh</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -c</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" rxthinkcmf.laravel13.naivevue</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> backup_2026-10-01.sql</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 整卷备份(停机快照)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> down</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> run</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --rm</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -v</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-laravel13_mysql_data:/data</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -v</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $(</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">pwd</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">:/backup</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> alpine</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> tar</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> czf</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /backup/mysql_data.tar.gz</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -C</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /data</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> .</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> up</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -d</span></span></code></pre></div><p>更多方案见 <a href="/zh/deploy/backup.html">11.9 备份与恢复</a>。</p><h2 id="故障排查" tabindex="-1">故障排查 <a class="header-anchor" href="#故障排查" aria-label="Permalink to "故障排查""></a></h2><table tabindex="0"><thead><tr><th>症状</th><th>排查</th><th>处理</th></tr></thead><tbody><tr><td>启动报 dependency failed to start</td><td><code>docker compose logs mysql</code></td><td>首次导入大 SQL 较慢,等待 healthy;密码错误则 <code>down -v</code> 后修正重来</td></tr><tr><td>页面 502 Bad Gateway</td><td><code>docker compose ps</code></td><td>app 未运行 → <code>docker compose logs app</code> 定位崩溃原因</td></tr><tr><td>页面 404</td><td><code>docker compose logs nginx</code></td><td>确认 <code>docker/nginx.conf</code> 挂载正确、入口在 <code>public/</code> 下</td></tr><tr><td>500 且无详情</td><td><code>docker compose logs app</code></td><td>生产 <code>APP_DEBUG=false</code> 时错误细节只在日志中</td></tr><tr><td>启动即退出,日志报 JWT_SECRET</td><td><code>.env</code> 或 <code>.env.docker</code> 密钥 < 32 字符</td><td>重新生成并重启</td></tr><tr><td>存储写入失败</td><td><code>storage/</code>、<code>bootstrap/cache/</code> 权限</td><td>镜像已 chown;挂载宿主机时确认目录对容器可写</td></tr><tr><td>备份 SQL 中文乱码</td><td>导出未指定字符集</td><td><code>mysqldump --default-character-set=utf8mb4</code></td></tr></tbody></table><h2 id="相关文档" tabindex="-1">相关文档 <a class="header-anchor" href="#相关文档" aria-label="Permalink to "相关文档""></a></h2><ul><li><a href="/zh/quickstart/docker.html">2.8 Docker 快速体验</a> — 本地一键启动</li><li><a href="/zh/deploy/backend.html">后端部署</a> — Nginx/Apache 非 Docker 详细配置</li><li><a href="/zh/deploy/frontend.html">前端部署</a> — Vue3 前端部署</li><li><a href="/zh/deploy/db-migrate.html">数据库迁移</a> — 多数据库迁移工具</li><li><a href="/zh/quickstart/env-vars.html">环境变量参考</a> — 完整配置项说明</li></ul>`,63)])])}const g=i(p,[["render",h]]);export{c as __pageData,g as default};
|