好物分享
我们后面努力

1Panel 2.0 容器化部署 CRMEB Pro (Swoole) 全链路踩坑与最佳实践指南

SEO 关键词: 1Panel, CRMEB Pro, Swoole, Docker 容器通信, Nginx 502, Supervisor, ThinkPHP, 运维部署, 二次开发

适用场景:1Panel v2.x 容器化环境 + CRMEB Pro v3.x (Swoole)

核心痛点:解决容器网络隔离、配置加载失败、Nginx 502/404、开发调试繁琐问题。

第一章:基础架构搭建 (只做一次)

在 1Panel 中,PHP 容器(运行环境)默认无法连接 Redis/MySQL 容器(应用商店)。必须手动打通网络。

1.1 容器网络“搭桥”

不要指望 127.0.0.1,必须让 PHP 容器加入 Redis 所在的网络。

Bash

# === 复制以下命令块执行 ===

# 1. 获取 Redis 所在网络名称 (自动侦测)
NET_NAME=$(docker inspect -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}}{{end}}' 1Panel-redis-lIVN)
echo "侦测到网络: $NET_NAME"

# 2. 将 PHP 容器加入该网络
docker network connect $NET_NAME PHP_8_0 2>/dev/null || echo "网络已连通"

# 3. 验证连通性 (必须看到 Connection established 或类似成功提示)
docker exec -u 0 PHP_8_0 php -r '
    $r=new Redis(); 
    try{ 
        $r->connect("1Panel-redis-lIVN", 6379); 
        echo "✅ Redis 连接成功!\n"; 
    } catch(Exception $e){ 
        echo "❌ 失败: ".$e->getMessage()."\n"; 
    }
'

第二章:标准配置文件 (复制即用)

2.1 环境配置 .env (1Panel 网页端修改)

  • 文件路径/www/sites/1gv.cn/index/.env
  • 严禁事项禁止在值后面加中文注释!禁止加括号!

Ini, TOML

[APP]
HOST=0.0.0.0
PORT=20199

[DATABASE]
DRIVER=mysql
TYPE=mysql
# 必须填容器真名,不能填 127.0.0.1
HOSTNAME=1Panel-mysql-DX5i
DATABASE=crmeb_pro
USERNAME=crmeb_user
# 👇 请替换为你的真实密码
PASSWORD=你的数据库密码
HOSTPORT=3306
CHARSET=utf8
DEBUG=true

[REDIS]
# 必须填容器真名
HOSTNAME=1Panel-redis-lIVN
PORT=6379
# 👇 请替换为你的真实密码
PASSWORD=你的Redis密码
SELECT=0

[QUEUE]
LISTEN_NAME=
BATCH_LISTEN_NAME=

2.2 守护进程配置 Supervisor (SSH 端修改)

  • 文件路径/etc/supervisor/conf.d/crmeb.conf
  • 核心逻辑:使用 docker exec 穿透;去掉 start 参数。

Bash

# === 复制以下命令生成配置文件 ===
cat > /etc/supervisor/conf.d/crmeb.conf <<EOF

[program:crmeb_pro]

# ✅ 核心命令:无 start 参数,使用 docker exec 穿透 command=/usr/bin/docker exec -u 0 -w /www/sites/1gv.cn/index PHP_8_0 php think swoole process_name=%(program_name)s numprocs=1 autostart=true autorestart=true startsecs=3 startretries=10 stopsignal=QUIT stopasgroup=true killasgroup=true # 日志直接输出到项目目录,方便在 1Panel 网页查看 stdout_logfile=/www/sites/1gv.cn/index/runtime/supervisor_out.log stderr_logfile=/www/sites/1gv.cn/index/runtime/supervisor_err.log stdout_logfile_maxbytes=10MB stderr_logfile_maxbytes=10MB EOF # === 重新加载配置 === supervisorctl update


第三章:二次开发效率工具 (必装)

你提到需要“频繁重启”和“方便快捷”。每次都敲长命令是低效的。请在 SSH 终端设置以下 快捷指令 (Alias)

3.1 注入快捷命令

Bash

# === 复制以下命令块执行 ===

# 1. 重载代码 (Dev Reload)
# 适用场景:修改了 PHP 业务代码 (Controller/Service),想不中断连接生效
echo "alias dev-reload='docker exec -u 0 -w /www/sites/1gv.cn/index PHP_8_0 php think swoole reload'" >> ~/.bashrc

# 2. 彻底重启 (Dev Restart) - 最常用!
# 适用场景:修改了 .env、config、安装了新扩展、或者单纯想重置环境
# 逻辑:清空缓存 -> 重启 Supervisor -> 查看状态
echo "alias dev-restart='docker exec -u 0 -w /www/sites/1gv.cn/index PHP_8_0 rm -rf runtime/cache runtime/temp runtime/log && supervisorctl restart crmeb_pro && sleep 2 && supervisorctl status crmeb_pro'" >> ~/.bashrc

# 3. 查看报错 (Dev Log)
# 适用场景:服务启动失败,想看为什么
echo "alias dev-log='tail -f /www/sites/1gv.cn/index/runtime/supervisor_err.log'" >> ~/.bashrc

# 4. 进入容器 (Dev Shell)
# 适用场景:需要进去执行 composer 或 php 命令
echo "alias dev-shell='docker exec -it -u 0 -w /www/sites/1gv.cn/index PHP_8_0 /bin/sh'" >> ~/.bashrc

# 使配置立即生效
source ~/.bashrc

echo "✅ 开发快捷键已安装!"
echo "输入 dev-restart 即可一键重启"
echo "输入 dev-log 可实时查看报错"

3.2 二次开发常用操作表

你的操作你应该执行的命令原理
修改了 .env 文件dev-restart必须重启进程才能读取新环境变量
修改了 config/*.phpdev-restart必须重启进程才能读取新配置
修改了 PHP 逻辑代码dev-reload (或等待热更)平滑重载 Worker 进程,用户无感知
网站突然打不开 (502)dev-log查看报错日志,通常是代码语法错误
安装了 composer 包dev-restart需要重启以加载新类库

第四章:Nginx 生产环境标准配置 (The Production Config)

注意: 安装阶段我们使用了“透传模式”(把所有流量给 Swoole)。当你安装完成并准备正式运营时,必须切换回 “生产模式”

生产模式优势

  1. 性能提升:图片、JS、CSS 由 Nginx 直接处理,不再消耗 Swoole 的 CPU 资源。
  2. 安全加固:禁止直接访问 .env 等敏感文件。
  3. 缓存优化:为静态资源添加浏览器缓存头。

操作步骤

  1. 首先执行 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' PHP_8_0 获取 PHP 容器 IP (例如 172.18.0.4)。
  2. 在 1Panel 网站配置中,用下方代码完全覆盖原有配置。

Nginx

# =========================================================
# CRMEB Pro 3.5 生产环境配置 (1Panel 标准版)
# =========================================================

# 定义上游 Swoole 服务
# ⚠️ 必须修改 IP 为你的 PHP 容器真实 IP
upstream crmeb_swoole {
    server 172.18.0.4:20199;
    keepalive 256;
}

server {
    listen 80;
    listen 443 ssl http2;
    server_name 1gv.cn; # 你的域名

    # ⚠️ 必须修改为 1Panel 的真实路径
    root /www/sites/1gv.cn/index/public;
    index index.php index.html;

    # 日志路径 (1Panel 默认)
    access_log /www/sites/1gv.cn/log/access.log main;
    error_log /www/sites/1gv.cn/log/error.log;

    # SSL 配置 (1Panel 默认,保持不变)
    ssl_certificate /www/sites/1gv.cn/ssl/fullchain.pem;
    ssl_certificate_key /www/sites/1gv.cn/ssl/privkey.pem;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";

    # ================= 生产环境路由逻辑 =================

    # 1. 静态资源加速 (Nginx 直接处理,不经过 Swoole)
    # 包括图片、CSS、JS、字体文件
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|woff|ttf|svg|eot)$ {
        expires 7d;      # 开启浏览器缓存 7 天
        access_log off;  # 关闭访问日志,节省磁盘空间
        try_files $uri @swoole; # 兜底:如果文件不存在,才问 Swoole (处理动态生成的图片)
    }

    # 2. 上传目录单独处理
    location ^~ /uploads/ {
        expires 7d;
    }

    # 3. 禁止访问敏感文件 (安全加固)
    location ~ /(\.env|\.git|\.htaccess|composer\.json|composer\.lock) {
        deny all;
    }

    # 4. 核心业务转发 (所有其他请求 -> Swoole)
    location / {
        proxy_pass http://crmeb_swoole;

        # 代理头设置
        proxy_http_version 1.1;
        proxy_read_timeout 360s;   
        proxy_redirect off; 

        # WebSocket 支持 (聊天系统必须)
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 传递真实 IP
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header REMOTE-HOST $remote_addr;

        add_header X-Cache $upstream_cache_status;
    }

    # 5. PHP 脚本转发 (兼容旧逻辑)
    location ~* \.php$ {
        proxy_pass http://crmeb_swoole;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 6. 定义 @swoole 命名位置 (作为兜底)
    location @swoole {
        proxy_pass http://crmeb_swoole;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 404 页面
    error_page 404 /404.html;
}

第五章:灾难恢复手册 (Panic Button)

在二次开发过程中,如果系统突然挂了,请按以下决策树进行自救。

场景 1:502 Bad Gateway

  • 现象:浏览器显示 502。
  • 原因:Swoole 进程挂了,或者 Nginx 连不上 Swoole。
  • 自救指令
    1. supervisorctl status crmeb_pro (看进程是否活着)
    2. 如果活着 -> 检查 Nginx 配置里的 IP 是否变了。
    3. 如果死了 (BACKOFF/EXITED) -> dev-log (看报错)。

场景 2:修改代码不生效

  • 现象:改了 PHP 逻辑,刷新页面还是旧的。
  • 原因:OPCache 缓存或 Swoole 内存驻留。
  • 自救指令dev-reload (轻量级重载) 或 dev-restart (强制重启)。

场景 3:权限错误 (Permission Denied)

  • 现象:上传图片失败,或日志显示无法写入。
  • 原因:Docker 容器内的 www-data 用户对宿主机挂载的目录没有写权限。
  • 自救指令:Bash# 简单粗暴给权限 (开发环境推荐) chmod -R 777 /www/sites/1gv.cn/index/public/uploads chmod -R 777 /www/sites/1gv.cn/index/runtime

📝 总结:为什么这次部署这么难?

这次部署之所以曲折,是因为你正好撞上了 三个维度的复杂性叠加

  1. 架构复杂性:CRMEB Pro 使用 Swoole,而不是传统的 PHP-FPM。它是一个常驻内存的服务,这本身就比普通 PHP 网站难维护。
  2. 环境隔离性:1Panel 2.0 强制执行更严格的 Docker 网络隔离。以前在宝塔上 127.0.0.1 随便连,现在必须理解 Docker Network。
  3. 配置敏感性:ThinkPHP 框架对配置文件格式的苛刻要求(不能有括号、注释),导致了最开始的启动失败。

现在的你,已经拥有了一套完整的、基于容器化的高性能开发环境。祝你的二次开发顺利!

赞(0) 打赏
未经允许不得转载:九五鹿 » 1Panel 2.0 容器化部署 CRMEB Pro (Swoole) 全链路踩坑与最佳实践指南

评论 抢沙发

我们的商品一定会让你满意的

我们的商品包含打印纸,收银纸,小票标签等各种打印设备和打印纸

获取报价产品介绍

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册