Files
c-relay-pg/admin/README.md
T

3.7 KiB

C-Relay-PG PHP Admin Page

A traditional PHP admin interface for the caching service that connects directly to PostgreSQL, bypassing the NIP-44 64KB encryption limit of the Nostr admin API. Handles thousands of followed pubkeys via server-side pagination.

Quick Start

1. Install PHP + PHP-FPM + PostgreSQL extension

# Debian/Ubuntu
sudo apt install php-fpm php-pgsql

# RHEL/Fedora/Alma
sudo dnf install php-fpm php-pgsql

2. Copy admin files to the server

sudo mkdir -p /opt/c-relay-pg/admin
sudo cp -r admin/* /opt/c-relay-pg/admin/

3. Configure database credentials

Edit /opt/c-relay-pg/admin/lib/config.php and set the PostgreSQL connection parameters to match your relay's --db-* flags:

return [
    'db_host'     => 'localhost',
    'db_port'     => '5432',
    'db_name'     => 'crelay',
    'db_user'     => 'crelay',
    'db_password' => 'crelay',
    // ...
];

4. Set up HTTP Basic Auth

sudo htpasswd -c /opt/c-relay-pg/admin/.htpasswd admin
# Enter a password when prompted

5. Add nginx location block

Add this to your existing nginx server block (the one that proxies to the relay on port 8888):

# PHP admin page for caching service
location /admin/ {
    alias /opt/c-relay-pg/admin/;
    index index.php;

    auth_basic "Relay Admin";
    auth_basic_user_file /opt/c-relay-pg/admin/.htpasswd;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }

    # Deny access to the lib/ directory (contains DB credentials)
    location ^~ /admin/lib/ {
        deny all;
    }
}

Note: The fastcgi_pass socket path varies by distro:

  • Debian/Ubuntu: unix:/run/php/php8.2-fpm.sock
  • RHEL/Fedora: unix:/run/php-fpm/www.sock

Check with: ls /run/php/ or ls /run/php-fpm/

6. Reload nginx

sudo nginx -t && sudo systemctl reload nginx

7. Visit the admin page

https://relay.yourdomain.com/admin/

Enter the HTTP Basic Auth credentials you set in step 4.

Pages

Page URL Description
Dashboard /admin/ Service state, backfill progress, error summary, active target
Follows /admin/follows.php Paginated followed-pubkey table with names, event counts, relay status
Relays /admin/relays.php Per (author, relay) backfill progress with descriptive error statuses
Config /admin/config-edit.php Read/edit caching config values; bumps config generation on save
Inbox /admin/inbox.php Queue depth monitor for caching_event_inbox

Security

  • HTTP Basic Auth protects all pages (nginx auth_basic)
  • lib/ directory denied via nginx (contains DB credentials)
  • PDO prepared statements everywhere (no SQL injection)
  • HTTPS via existing nginx SSL config
  • No CORS needed — same origin as the relay

How It Works

The PHP pages query PostgreSQL directly using PDO with the same crelay database user the relay uses. The dashboard auto-refreshes every 10 seconds via AJAX polling of api/status.php. Paginated tables (follows, relays) use server-side pagination with LIMIT/OFFSET.

The config editor writes to the config table and bumps caching_config_generation, which the caching service detects and hot-reloads — no relay restart needed.

Upgrading to Real-Time (Future)

If you later need true push updates (sub-second), you can add a small Node.js WebSocket server alongside the PHP pages that uses PostgreSQL LISTEN/NOTIFY to push updates to connected browsers. The PHP pages and JSON endpoints are reusable — the WebSocket server would just replace the polling fetch() calls in the JavaScript.