diff --git a/deploy_update.sh b/deploy_update.sh index e413b6c..0cdbc8c 100644 --- a/deploy_update.sh +++ b/deploy_update.sh @@ -9,6 +9,22 @@ NC='\033[0m' PROJECT_ROOT="/www/wwwroot/chat.ay.lc" # <--- 确认这里的路径是否正确 export COMPOSER_ALLOW_SUPERUSER=1 +SUPERVISORCTL_BIN="" +PHP_BIN="" + +for candidate in /usr/bin/supervisorctl /usr/local/bin/supervisorctl /www/server/panel/pyenv/bin/supervisorctl; do + if [ -x "$candidate" ]; then + SUPERVISORCTL_BIN="$candidate" + break + fi +done + +for candidate in /www/server/php/84/bin/php /usr/bin/php /usr/local/bin/php; do + if [ -x "$candidate" ]; then + PHP_BIN="$candidate" + break + fi +done echo -e "${BLUE}========================================${NC}" echo -e "${BLUE} 🚀 Laravel 稳健更新脚本 (带严格检查) ${NC}" @@ -16,6 +32,14 @@ echo -e "${BLUE}========================================${NC}" cd "$PROJECT_ROOT" || { echo -e "${RED}❌ 无法进入项目目录:$PROJECT_ROOT${NC}"; exit 1; } +if [ -z "$PHP_BIN" ]; then + echo -e "${RED}❌ 未找到可用 PHP 可执行文件,请确认服务器已安装 PHP 8.4。${NC}" + exit 1 +fi + +PHP_VERSION=$("$PHP_BIN" -r 'echo PHP_VERSION;' 2>/dev/null) +echo -e "${BLUE}使用 PHP:$PHP_BIN (版本:${PHP_VERSION:-unknown})${NC}" + # 1. Git Pull(先重置 lock 文件,避免服务器环境差异导致冲突) echo -e "${YELLOW}[1/8] 拉取代码...${NC}" git checkout -- composer.lock package-lock.json 2>/dev/null || true @@ -58,7 +82,7 @@ composer dump-autoload --no-dev --optimize --classmap-authoritative --no-interac if [ $? -ne 0 ]; then echo -e "${RED}❌ Composer autoload 重建失败${NC}"; exit 1; fi # 用当前 PHP 直接加载 Laravel autoload,提前暴露 vendor 缺文件 / 权限 / autoload 缓存问题 -php -d opcache.enable_cli=0 -r "require __DIR__.'/vendor/autoload.php'; echo 'Composer autoload OK'.PHP_EOL;" +"$PHP_BIN" -d opcache.enable_cli=0 -r "require __DIR__.'/vendor/autoload.php'; echo 'Composer autoload OK'.PHP_EOL;" if [ $? -ne 0 ]; then echo -e "${RED}========================================${NC}" echo -e "${RED} ❌ 致命错误:PHP 无法加载 vendor/autoload.php! ${NC}" @@ -76,48 +100,50 @@ echo -e "${GREEN}✅ 前端资源构建完成。${NC}" # 4. 数据库迁移 echo -e "${YELLOW}[4/8] 数据库迁移...${NC}" -php artisan migrate --force +"$PHP_BIN" artisan migrate --force # 5. 优化 echo -e "${YELLOW}[5/8] 生产环境优化...${NC}" # 注意:optimize 命令内部已经包含了 config:cache, route:cache, event:cache,此处无须多余处理 -php artisan optimize:clear && php artisan optimize && php artisan view:cache +"$PHP_BIN" artisan optimize:clear && "$PHP_BIN" artisan optimize && "$PHP_BIN" artisan view:cache # 6. 重启 Horizon / 队列进程 echo -e "${YELLOW}[6/8] 重启 Horizon...${NC}" -php artisan horizon:terminate +"$PHP_BIN" artisan horizon:terminate >/dev/null 2>&1 || true +if [ -n "$SUPERVISORCTL_BIN" ]; then + "$SUPERVISORCTL_BIN" restart horizon >/dev/null 2>&1 || "$SUPERVISORCTL_BIN" restart horizon:* >/dev/null 2>&1 || true +fi # 7. 重启 Reverb,确保长驻 WebSocket 进程加载最新代码和配置 echo -e "${YELLOW}[7/8] 重启 Reverb...${NC}" REVERB_RESTARTED=0 REVERB_CAN_AUTO_RESTART=0 -SUPERVISOR_REVERB_TARGETS="" +SUPERVISOR_REVERB_TARGET="" # 先探测是否存在可自动拉起 Reverb 的进程管理器,避免在纯手工启动场景下执行 reverb:restart 后把聊天室停掉。 -if command -v supervisorctl >/dev/null 2>&1; then - SUPERVISOR_REVERB_TARGETS=$(supervisorctl status 2>/dev/null | awk '/reverb|broadcast|websocket/ {print $1}') - if [ -n "$SUPERVISOR_REVERB_TARGETS" ]; then +if [ -n "$SUPERVISORCTL_BIN" ]; then + if "$SUPERVISORCTL_BIN" status reverb >/dev/null 2>&1; then + SUPERVISOR_REVERB_TARGET="reverb" + REVERB_CAN_AUTO_RESTART=1 + elif "$SUPERVISORCTL_BIN" status reverb:* >/dev/null 2>&1; then + SUPERVISOR_REVERB_TARGET="reverb:*" REVERB_CAN_AUTO_RESTART=1 fi fi # Laravel 官方文档说明:reverb:restart 适合在 Supervisor 等进程管理器托管下使用。 if [ "$REVERB_CAN_AUTO_RESTART" -eq 1 ]; then - php artisan reverb:restart >/dev/null 2>&1 + "$PHP_BIN" artisan reverb:restart >/dev/null 2>&1 if [ $? -eq 0 ]; then REVERB_RESTARTED=1 echo -e "${GREEN}✅ 已执行 php artisan reverb:restart。${NC}" fi # 若线上通过 Supervisor 托管 reverb:start,再补一次显式 restart,尽量确保进程被拉起。 - if [ -n "$SUPERVISOR_REVERB_TARGETS" ]; then - while IFS= read -r target; do - if [ -n "$target" ]; then - supervisorctl restart "$target" >/dev/null 2>&1 || true - REVERB_RESTARTED=1 - fi - done <<< "$SUPERVISOR_REVERB_TARGETS" - echo -e "${GREEN}✅ 已尝试重启 Supervisor 托管的 Reverb 相关进程。${NC}" + if [ -n "$SUPERVISOR_REVERB_TARGET" ]; then + "$SUPERVISORCTL_BIN" restart "$SUPERVISOR_REVERB_TARGET" >/dev/null 2>&1 || true + REVERB_RESTARTED=1 + echo -e "${GREEN}✅ 已尝试重启 Supervisor 托管的 Reverb 进程。${NC}" fi else echo -e "${YELLOW}⚠️ 未检测到 Reverb 进程管理器,已跳过 reverb:restart,避免把手工启动的聊天室长连接服务停掉。${NC}"