fix(deploy): make install/update redis-independent and clean stale octane state

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
xboard
2026-04-19 23:23:27 +08:00
parent dc8fbd1839
commit cb8c1743dc
4 changed files with 61 additions and 12 deletions
+23 -1
View File
@@ -116,13 +116,35 @@ export OCTANE_WORKERS OCTANE_TASK_WORKERS OCTANE_MAX_REQUESTS \
echo "[entrypoint] Auto-tune (profile=${RESOURCE_PROFILE}): cpus=${CPUS} mem=${MEM_MIB}MiB slots=${SLOTS} -> octane=${OCTANE_WORKERS} horizon(dp/biz/notif)=${HORIZON_DATA_PIPELINE_MAX}/${HORIZON_BUSINESS_MAX}/${HORIZON_NOTIFICATION_MAX} horizon_worker_mem=${HORIZON_WORKER_MEMORY_MB}MB" echo "[entrypoint] Auto-tune (profile=${RESOURCE_PROFILE}): cpus=${CPUS} mem=${MEM_MIB}MiB slots=${SLOTS} -> octane=${OCTANE_WORKERS} horizon(dp/biz/notif)=${HORIZON_DATA_PIPELINE_MAX}/${HORIZON_BUSINESS_MAX}/${HORIZON_NOTIFICATION_MAX} horizon_worker_mem=${HORIZON_WORKER_MEMORY_MB}MB"
echo "[entrypoint] Horizon supervisors use balance=auto with minProcesses=1, so they scale up to the cap on demand and back down when idle." echo "[entrypoint] Horizon supervisors use balance=auto with minProcesses=1, so they scale up to the cap on demand and back down when idle."
redis_reachable() {
local host port
host=$(grep -E '^REDIS_HOST=' /www/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
port=$(grep -E '^REDIS_PORT=' /www/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
command -v redis-cli >/dev/null 2>&1 || return 1
[ -n "$host" ] || return 1
case "$host" in
/*) [ -S "$host" ] && redis-cli -s "$host" ping 2>/dev/null | grep -q PONG ;;
*) redis-cli -h "$host" -p "${port:-6379}" ping 2>/dev/null | grep -q PONG ;;
esac
}
if [ ! -s /www/.env ] || ! grep -qE '^INSTALLED=(1|true)$' /www/.env || echo " $* " | grep -q ' xboard:install '; then if [ ! -s /www/.env ] || ! grep -qE '^INSTALLED=(1|true)$' /www/.env || echo " $* " | grep -q ' xboard:install '; then
echo "[entrypoint] Skipping xboard:update (not yet installed or running xboard:install)." echo "[entrypoint] Skipping xboard:update (not yet installed or running xboard:install)."
else else
echo "[entrypoint] Running xboard:update..." if redis_reachable; then
echo "[entrypoint] Running xboard:update (redis reachable, real drivers)..."
php /www/artisan xboard:update --no-interaction || \ php /www/artisan xboard:update --no-interaction || \
echo "[entrypoint] WARNING: xboard:update failed; continuing so supervisor can boot anyway." >&2 echo "[entrypoint] WARNING: xboard:update failed; continuing so supervisor can boot anyway." >&2
else
echo "[entrypoint] Running xboard:update (redis not yet up, using array/sync drivers)..."
CACHE_DRIVER=array QUEUE_CONNECTION=sync SESSION_DRIVER=array \
php /www/artisan xboard:update --no-interaction || \
echo "[entrypoint] WARNING: xboard:update failed; continuing so supervisor can boot anyway." >&2
fi
fi fi
echo "[entrypoint] Starting services (caddy=${ENABLE_CADDY} web=${ENABLE_WEB} horizon=${ENABLE_HORIZON} ws=${ENABLE_WS_SERVER})..." echo "[entrypoint] Starting services (caddy=${ENABLE_CADDY} web=${ENABLE_WEB} horizon=${ENABLE_HORIZON} ws=${ENABLE_WS_SERVER})..."
# Drop stale Octane/WorkerMan state files so the new master does not signal
# PIDs left over from a previous container run (causes Swoole kill EPERM).
rm -f /www/storage/logs/octane-server-state.json /www/storage/logs/xboard-ws-server.pid 2>/dev/null || true
exec "$@" exec "$@"
+2
View File
@@ -47,6 +47,8 @@ command=redis-server --dir /data
--save 900 1 --save 900 1
--save 300 10 --save 300 10
--save 60 10000 --save 60 10000
--bind 127.0.0.1
--port 6379
--unixsocket /data/redis.sock --unixsocket /data/redis.sock
--unixsocketperm 777 --unixsocketperm 777
autostart=%(ENV_ENABLE_REDIS)s autostart=%(ENV_ENABLE_REDIS)s
+24 -3
View File
@@ -101,15 +101,17 @@ class XboardInstall extends Command
$isReidsValid = false; $isReidsValid = false;
while (!$isReidsValid) { while (!$isReidsValid) {
// 判断是否为Docker环境 // 判断是否为Docker环境
if ($isDocker == 'true' && ($enableRedis || confirm(label: '是否启用Docker内置的Redis', default: true, yes: '启用', no: '不启用'))) { $useBuiltinRedis = $isDocker && ($enableRedis || confirm(label: '是否启用Docker内置的Redis', default: true, yes: '启用', no: '不启用'));
if ($useBuiltinRedis) {
$envConfig['REDIS_HOST'] = '/data/redis.sock'; $envConfig['REDIS_HOST'] = '/data/redis.sock';
$envConfig['REDIS_PORT'] = 0; $envConfig['REDIS_PORT'] = 0;
$envConfig['REDIS_PASSWORD'] = null; $envConfig['REDIS_PASSWORD'] = null;
} else { $isReidsValid = true;
break;
}
$envConfig['REDIS_HOST'] = text(label: '请输入Redis地址', default: '127.0.0.1', required: true); $envConfig['REDIS_HOST'] = text(label: '请输入Redis地址', default: '127.0.0.1', required: true);
$envConfig['REDIS_PORT'] = text(label: '请输入Redis端口', default: '6379', required: true); $envConfig['REDIS_PORT'] = text(label: '请输入Redis端口', default: '6379', required: true);
$envConfig['REDIS_PASSWORD'] = text(label: '请输入redis密码(默认: null)', default: ''); $envConfig['REDIS_PASSWORD'] = text(label: '请输入redis密码(默认: null)', default: '');
}
$redisConfig = [ $redisConfig = [
'client' => 'phpredis', 'client' => 'phpredis',
'default' => [ 'default' => [
@@ -148,6 +150,20 @@ class XboardInstall extends Command
$password = Helper::guid(false); $password = Helper::guid(false);
$this->saveToEnv($envConfig); $this->saveToEnv($envConfig);
$installDriverOverrides = [
'CACHE_DRIVER' => 'array',
'QUEUE_CONNECTION' => 'sync',
'SESSION_DRIVER' => 'array',
];
foreach ($installDriverOverrides as $key => $value) {
putenv("{$key}={$value}");
$_ENV[$key] = $value;
$_SERVER[$key] = $value;
}
Config::set('cache.default', 'array');
Config::set('queue.default', 'sync');
Config::set('session.driver', 'array');
$this->call('config:cache'); $this->call('config:cache');
Artisan::call('cache:clear'); Artisan::call('cache:clear');
$this->info('正在导入数据库请稍等...'); $this->info('正在导入数据库请稍等...');
@@ -170,6 +186,11 @@ class XboardInstall extends Command
$this->info("访问 http(s)://你的站点/{$defaultSecurePath} 进入管理面板,你可以在用户中心修改你的密码。"); $this->info("访问 http(s)://你的站点/{$defaultSecurePath} 进入管理面板,你可以在用户中心修改你的密码。");
$envConfig['INSTALLED'] = true; $envConfig['INSTALLED'] = true;
$this->saveToEnv($envConfig); $this->saveToEnv($envConfig);
foreach (array_keys($installDriverOverrides) as $key) {
putenv($key);
unset($_ENV[$key], $_SERVER[$key]);
}
Artisan::call('config:clear');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->error($e); $this->error($e);
} }
+4
View File
@@ -51,11 +51,15 @@ class XboardUpdate extends Command
$updateService->updateVersionCache(); $updateService->updateVersionCache();
$themeService = app(ThemeService::class); $themeService = app(ThemeService::class);
$themeService->refreshCurrentTheme(); $themeService->refreshCurrentTheme();
if (config('queue.default') === 'sync') {
$this->info('horizon:terminate skipped (sync queue, no workers to terminate).');
} else {
try { try {
Artisan::call('horizon:terminate'); Artisan::call('horizon:terminate');
} catch (\Throwable $e) { } catch (\Throwable $e) {
$this->warn('horizon:terminate skipped: ' . $e->getMessage()); $this->warn('horizon:terminate skipped: ' . $e->getMessage());
} }
}
$this->info('更新完毕,队列服务已重启,你无需进行任何操作。'); $this->info('更新完毕,队列服务已重启,你无需进行任何操作。');
} }
} }