dnss / entrypoint.sh
zipusyan's picture
Update entrypoint.sh
eb4bad5 verified
#!/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 <<EOSQL
FLUSH PRIVILEGES;
CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY '${DB_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'127.0.0.1' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'127.0.0.1';
EOSQL
echo "=== Creating tables ==="
mysql -u root --socket=/run/mysqld/mysqld.sock "${DB_NAME}" < /app/www/app/sql/install.sql
echo "=== Creating admin user ==="
SYS_KEY=$(php -r "echo bin2hex(random_bytes(8));")
ADMIN_HASH=$(php -r "echo password_hash('${ADMIN_PASSWORD}', PASSWORD_DEFAULT);")
mysql -u root --socket=/run/mysqld/mysqld.sock "${DB_NAME}" <<EOSQL
REPLACE INTO \`${DB_PREFIX}config\` VALUES ('sys_key', '${SYS_KEY}');
INSERT INTO \`${DB_PREFIX}user\` (\`username\`,\`password\`,\`level\`,\`regtime\`,\`lasttime\`,\`status\`) VALUES ('${ADMIN_USER}', '${ADMIN_HASH}', 2, NOW(), NOW(), 1);
EOSQL
echo "=== Setting root password ==="
mysql -u root --socket=/run/mysqld/mysqld.sock <<EOSQL
ALTER USER 'root'@'localhost' IDENTIFIED BY '${DB_ROOT_PASSWORD}';
FLUSH PRIVILEGES;
EOSQL
kill $MYSQL_PID 2>/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 <<EOF
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = ${DB_NAME}
USERNAME = ${DB_USER}
PASSWORD = ${DB_PASSWORD}
HOSTPORT = ${DB_PORT}
CHARSET = utf8mb4
PREFIX = ${DB_PREFIX}
DEBUG = true
[LANG]
default_lang = zh-cn
EOF
echo "=== .env written ==="
fi
# Always create diagnostic check.php
cat > /app/www/public/check.php <<'PHPEOF'
<?php
header('Content-Type: text/plain; charset=utf-8');
echo "===== PHP Probe v2 =====\n\n";
echo "PHP version: " . PHP_VERSION . "\n";
echo "PHP-FPM user: " . (function_exists('exec') ? exec('whoami') : 'N/A') . "\n";
echo "\n--- Runtime dirs ---\n";
$runtime = dirname(__DIR__) . '/runtime';
$dirs = ['temp', 'cache', 'session', 'log'];
foreach ($dirs as $d) {
$p = $runtime . '/' . $d;
$exists = is_dir($p) ? 'dir' : (is_file($p) ? 'FILE' : 'NOT_EXIST');
$writable = is_writable($p) ? 'WRITABLE' : 'NOT_WRITABLE';
$perms = substr(sprintf('%o', fileperms($p)), -4);
$owner = function_exists('posix_getpwuid') ? posix_getpwuid(fileowner($p))['name'] ?? fileowner($p) : fileowner($p);
echo " $d: $exists | $writable | perms=$perms | owner=$owner\n";
}
echo "\n--- Test template compile ---\n";
$tmpFile = $runtime . '/temp/_test_compile.php';
$result = @file_put_contents($tmpFile, '<?php echo "ok";');
if ($result === false) {
echo " WRITE FAILED: " . error_get_last()['message'] . "\n";
} else {
echo " Write OK (" . $result . " bytes)\n";
@unlink($tmpFile);
}
echo "\n--- .env ---\n";
$f = dirname(__DIR__) . '/.env';
echo file_exists($f) ? "exists\n" . file_get_contents($f) : "MISSING\n";
echo "\n--- Database ---\n";
try {
$p = new PDO("mysql:host=127.0.0.1;port=3306;dbname=dnsmgr;charset=utf8mb4", "dnsmgr", "123456", [PDO::ATTR_ERRMODE => 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'
<?php
header('Content-Type: text/plain; charset=utf-8');
$orig = $_SERVER;
$_SERVER['REQUEST_URI'] = '/login';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$_SERVER['SCRIPT_FILENAME'] = '/app/www/public/index.php';
$_SERVER['PHP_SELF'] = '/index.php';
$_SERVER['QUERY_STRING'] = '';
$_SERVER['HTTPS'] = 'off';
$_SERVER['PATH_INFO'] = '';
$_SERVER['ORIG_PATH_INFO'] = '';
$_SERVER['DOCUMENT_ROOT'] = dirname(__DIR__) . '/public';
$_SERVER['SERVER_NAME'] = 'localhost';
$_SERVER['SERVER_PORT'] = '8081';
$_SERVER['HTTP_HOST'] = 'localhost:8081';
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
unset($_SERVER['argv']);
try {
require dirname(__DIR__) . '/vendor/autoload.php';
$app = new \think\App(dirname(__DIR__));
$http = $app->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 "$@"