#!/bin/sh set -e DB_ROOT_PASSWORD="123456" DB_NAME="dnsmgr" DB_USER="dnsmgr" DB_PASSWORD="123456" DB_PORT=3306 DB_PREFIX="dnsmgr_" ADMIN_USER="admin" ADMIN_PASSWORD="123456" INIT_FLAG="/var/lib/mysql/.initialized" # === HF Spaces persistent storage setup === # If /data/ exists (persistent volume), redirect runtime data there if [ -d "/data" ]; then echo "=== Persistent storage detected at /data ===" PERSISTENT=true # Create directory structure under /data/ for all runtime data mkdir -p /data/mysql mkdir -p /data/runtime/temp /data/runtime/cache /data/runtime/session /data/runtime/log mkdir -p /data/public/storage # Fix ownership chown -R mysql:mysql /data/mysql chown -R nginx:nginx /data/runtime /data/public # Symlink MySQL data dir → /data/mysql if [ ! -L /var/lib/mysql ]; then echo " Linking /var/lib/mysql -> /data/mysql" rm -rf /var/lib/mysql ln -sf /data/mysql /var/lib/mysql fi # Symlink ThinkPHP runtime → /data/runtime if [ ! -L /app/www/runtime ]; then echo " Linking /app/www/runtime -> /data/runtime" rm -rf /app/www/runtime ln -sf /data/runtime /app/www/runtime fi # Symlink public storage → /data/public/storage if [ ! -L /app/www/public/storage ]; then echo " Linking /app/www/public/storage -> /data/public/storage" rm -rf /app/www/public/storage ln -sf /data/public/storage /app/www/public/storage fi echo "=== Persistent storage ready ===" else echo "=== No persistent volume (/data), running ephemerally ===" PERSISTENT=false fi if [ ! -f "$INIT_FLAG" ]; then echo "=== Initializing MariaDB ===" mysql_install_db --datadir=/var/lib/mysql --user=mysql >/dev/null 2>&1 mysqld --datadir=/var/lib/mysql --user=mysql --skip-networking & MYSQL_PID=$! for i in $(seq 1 30); do if mysql -u root --socket=/run/mysqld/mysqld.sock -e "SELECT 1" >/dev/null 2>&1; then break fi sleep 1 done mysql -u root --socket=/run/mysqld/mysqld.sock </dev/null wait $MYSQL_PID 2>/dev/null || true touch "$INIT_FLAG" echo "=== MariaDB initialized ===" fi if [ ! -f /app/www/.env ]; then cat > /app/www/.env < /app/www/public/check.php <<'PHPEOF' PDO::ERRMODE_EXCEPTION, PDO::ATTR_TIMEOUT => 3]); echo "DB OK\nTables: " . implode(", ", $p->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN)) . "\n"; echo "Config:\n"; foreach ($p->query("SELECT `key`,`value` FROM dnsmgr_config") as $r) { echo " {$r['key']}={$r['value']}\n"; } echo "Users:\n"; foreach ($p->query("SELECT id,username,level,status FROM dnsmgr_user") as $r) { echo " {$r['id']} {$r['username']} lv{$r['level']} st{$r['status']}\n"; } } catch (Exception $e) { echo "DB ERROR: " . $e->getMessage() . "\n"; } echo "\n--- PHP-FPM error log (last 20 lines) ---\n"; $errorLog = ini_get('error_log'); if ($errorLog && is_file($errorLog)) { $lines = array_slice(file($errorLog), -20); foreach ($lines as $l) echo " $l"; } else { echo " error_log not configured or not found: " . ($errorLog ?: 'none') . "\n"; } echo "\n--- Runtime log (last 10 lines) ---\n"; $logFile = $runtime . '/log/' . date('Y-m-d') . '.log'; if (is_file($logFile)) { $lines = array_slice(file($logFile), -10); foreach ($lines as $l) echo " $l"; } else { echo " no log file at $logFile\n"; } echo "\n===== Done =====\n"; PHPEOF chown nginx:nginx /app/www/public/check.php 2>/dev/null || true echo "=== check.php created ===" cat > /app/www/public/rtest.php <<'PHPEOF' http; // 1. Show pathinfo resolution echo "=== Pathinfo ===\n"; $req = $app->make('request', [], true); echo "PATH_INFO: " . var_export($req->server('PATH_INFO'), true) . "\n"; echo "ORIG_PATH_INFO: " . var_export($req->server('ORIG_PATH_INFO'), true) . "\n"; echo "REQUEST_URI: " . var_export($req->server('REQUEST_URI'), true) . "\n"; echo "SCRIPT_NAME: " . var_export($req->server('SCRIPT_NAME'), true) . "\n"; echo "PHP_SELF: " . var_export($req->server('PHP_SELF'), true) . "\n"; echo "pathinfo(): " . $req->pathinfo() . "\n"; echo "baseUrl(): " . $req->baseUrl() . "\n"; echo "baseFile(): " . $req->baseFile() . "\n\n"; // 2. Load routes manually then list echo "=== Routes ===\n"; $routePath = $app->getRootPath() . 'route/'; $files = glob($routePath . '*.php'); if ($files) { foreach ($files as $file) { include $file; } } $routeService = $app->make('route'); $rules = $routeService->getRuleList(); echo "Total route rules: " . count($rules) . "\n"; foreach ($rules as $r) { $method = $r['method'] ?? '*'; $rule = $r['rule'] ?? '?'; $route = $r['route']; if ($route instanceof \Closure) { $route = 'Closure'; } elseif (is_array($route)) { $route = json_encode($route); } elseif (is_object($route)) { $route = get_class($route); } echo " $method $rule -> $route\n"; } echo "\n"; // 3. Now run the dispatch with /login PATH_INFO $_SERVER['PATH_INFO'] = '/login'; echo "=== Dispatch /login ===\n"; $response = $http->run(); echo "Code: " . $response->getCode() . "\n"; echo "Class: " . get_class($response) . "\n"; echo "Headers:\n"; foreach ($response->getHeader() as $k => $v) { echo " $k: $v\n"; } echo "Content (" . strlen($response->getContent()) . " bytes): " . substr($response->getContent(), 0, 500) . "\n"; } catch (\Throwable $e) { echo "EXCEPTION: " . get_class($e) . ": " . $e->getMessage() . "\n"; echo "File: " . $e->getFile() . ":" . $e->getLine() . "\n"; echo $e->getTraceAsString() . "\n"; } $_SERVER = $orig; PHPEOF chown nginx:nginx /app/www/public/rtest.php 2>/dev/null || true echo "=== rtest.php created ===" exec "$@"