Skip to content

Hub Admin Overview

The Hub Admin section covers running and operating a self-hosted Phlix Hub — the cloud directory + reverse-tunnel relay that lets your media servers be reached from anywhere.

This page is the entry point: it explains the web admin console (the Vue single-page app you manage the Hub from) and the operational CLI reference (the commands you run on the host). The rest of the section drills into install, capacity, tuning, monitoring, and policy.

The Hub web UI

Once the Hub is running, its web UI is the Vue single-page app (built on the shared @phlix/ui design system) served by the HTTP worker on the public port (default 8800). The bare root redirects into the appGET //app/servers — and the SPA is served at /app and every /app/* deep link; it handles its own sign-in. (The Hub's original server-rendered Smarty pages — /login, /my-servers, /claim-server, /manage-shares, … — still resolve directly, but the SPA is the front door now.)

The first account created becomes an admin automatically (see Install); the SPA reads is_admin from GET /api/v1/auth/me and shows the Admin nav entry only to admins.

Primary nav (any signed-in user)

PagePathWhat it does
My Servers/app/serversYour claimed servers + live heartbeat status; claim a new server here
Federation/app/federationPeer-hub federation: peers, cross-hub library shares, admin delegation
Shares/app/sharesLibraries you share and libraries shared with you, with permission levels

Admin console (admins only)

The gated Admin entry opens the shared admin console at /app/admin/* — five pages: Hub Dashboard, Users, Logs, Settings, and Audit Logs. It is backed by the /api/v1/admin/* API and is documented in full on the Admin Console page.

PagePath
Hub Dashboard/app/admin/dashboard
Users/app/admin/users
Logs/app/admin/logs
Settings/app/admin/settings
Audit Logs/app/admin/audit-logs

Admin-only pages and APIs are gated server-side by AdminMiddleware (401 auth.required when unauthenticated, 403 auth.not_admin for a non-admin) and require an account with the is_admin flag. The first registered user gets it automatically; there is no separate "create admin" step.

A machine-readable health probe is always available at /health:

bash
curl http://localhost:8800/health
# => {"status":"ok", ...}

Admin & operations CLI reference

The Hub is operated from the project root with plain PHP entry points — there is no separate hub binary. The two commands you use day-to-day are the process controller (public/index.php) and the migration runner (scripts/run-migrations.php).

Process control — public/index.php

The HTTP, relay, and client-relay workers are managed by Workerman, which exposes the standard start/stop verbs:

bash
php public/index.php start        # run in the foreground
php public/index.php start -d     # run as a daemon
php public/index.php stop         # stop all workers
php public/index.php restart      # stop, then start
php public/index.php reload       # graceful reload (zero-downtime code reload)
php public/index.php status       # show worker status
php public/index.php connections  # list active connections

Under systemd, use the foreground form (start) with Type=simple — see the install guide.

Database migrations — scripts/run-migrations.php

bash
php scripts/run-migrations.php

Applies every SQL file in migrations/ in order. The runner records what it has applied in a migrations table, so it is idempotent — re-running after a successful apply is a no-op. There is no destructive --force flag; to start over, drop and recreate the database, then re-run.

The ledger also stores a comment-normalized checksum of each applied file. If you hand-edit the SQL of a migration that has already run (a "rewrite-class" migration), the next run detects the changed content, logs a WARNING (via error_log() — it shows up in the deploy output / CLI stderr), re-applies the file, and refreshes its stored checksum, instead of skipping it forever on filename alone. Comment/header-only edits are ignored (comments are stripped before hashing), and migrations that pre-date the checksum column are backfilled without re-running — upgrading never mass-re-applies your existing schema. Because a re-applied file executes again, keep migrations re-run-safe (CREATE TABLE IF NOT EXISTS, additive/idempotent DDL).

JWT smoke test — scripts/smoke-jwt-roundtrip.php

bash
php scripts/smoke-jwt-roundtrip.php

Mints an access token with the Hub's configured secret, validates it back, and prints the decoded claims. Exits non-zero on mismatch — handy for confirming HUB_JWT_SECRET is wired up after a deploy.

Creating and promoting admins

There is no user-management CLI. Admins are bootstrapped by signup:

  • The first account registered at /signup is auto-promoted to admin.
  • Additional admins are granted by setting is_admin = 1 on their row in the users table.

Configuration at a glance

The Hub is configured entirely through HUB_* environment variables (database, JWT, public domain, ports). The Install page documents every variable and a full Ubuntu / Docker walkthrough.

Where to next

BSD-3-Clause