Vardo

Administration guide

Admin panel, system settings, user management, email configuration, and operational tasks.

The admin panel and system settings are available to users with isAppAdmin status. The first user created during setup is automatically promoted to app admin.

Admin panel

The admin panel at /admin has six tabs:

TabWhat it shows
OverviewStat cards (users, apps, deployments, templates) with sparklines, resource usage bars (CPU, memory, disk) and infrastructure service status
SystemRuntime info (Next.js version, Node.js version, uptime, memory RSS), infrastructure service health, auth method status and feature flag states
OrganizationsAll organizations across the instance
UsersAll users with email, auth methods and creation date. Admins can promote or revoke app admin status.
MaintenanceDocker prune — removes unused images, stopped containers and dangling networks
MetricsInfrastructure and business metrics across all organizations

A System settings link in the toolbar opens /admin/settings.

System settings

System settings are stored in the system_settings database table as encrypted key-value pairs (AES-256-GCM at rest). Settings can also live in vardo.yml / vardo.secrets.yml — config file values always take priority over the database.

Overview

Shows a summary of all configured settings at a glance — email provider, GitHub App status, backup target count, feature flag states and the active domain.

General

SettingDescription
Instance nameDisplay name shown in the UI
DomainPublic domain for this Vardo instance (used for redirect URLs and TLS)
Base domainWhen set, apps receive subdomains automatically (e.g. myapp.yourdomain.com)

Email

Email is required for magic link sign-in and notification delivery. Four providers are supported.

Mailpace

# vardo.yml
email:
  provider: mailpace
  fromEmail: [email protected]
  fromName: Vardo

# vardo.secrets.yml
email:
  apiKey: "<mailpace api key>"

Resend

# vardo.yml
email:
  provider: resend
  fromEmail: [email protected]
  fromName: Vardo

# vardo.secrets.yml
email:
  apiKey: "<resend api key>"

Postmark

# vardo.yml
email:
  provider: postmark
  fromEmail: [email protected]
  fromName: Vardo

# vardo.secrets.yml
email:
  apiKey: "<postmark server token>"

SMTP

# vardo.yml
email:
  provider: smtp
  fromEmail: [email protected]
  fromName: Vardo
  smtpHost: smtp.yourprovider.com
  smtpPort: 587
  smtpUser: [email protected]

# vardo.secrets.yml
email:
  smtpPass: "<smtp password>"

Use the Send test email button in the admin UI to verify delivery after configuring.

Environment variable fallback — if no database or file config is set, Vardo reads:

  • RESEND_API_KEY — Resend provider
  • MAILPACE_API_TOKEN — Mailpace provider
  • SMTP_HOST + SMTP_USER + SMTP_PASS — SMTP provider

The ALLOW_SMTP provider restriction can gate whether SMTP is offered during setup.

Authentication

Controls sign-in options and registration behavior:

SettingDescription
Registration modeopen — anyone can sign up; closed — invitations only; approval — sign-ups require admin approval
Session durationHow long sessions remain valid (default: 7 days, auto-refresh enabled)

GitHub OAuth (GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET) enables the Sign in with GitHub button. This is separate from the GitHub App integration used for deployments.

The passwordAuth feature flag controls whether email/password sign-in is available. Disabling it forces passkey, magic link or OAuth authentication.

The ALLOW_PASSWORD_AUTH environment variable provides an additional gate — both the feature flag and the env var must allow password auth for it to appear.

Feature flags

Feature flags control which sections of the UI and API are active. Resolution order:

  1. vardo.yml features: block (highest priority)
  2. system_settings table in the database
  3. Default: enabled

Core features (projects, apps, deployments, metrics, logs) can't be disabled.

FlagLabelDefaultControls
uiWeb UIonThe web dashboard. Disabling makes Vardo API-only — shows a message directing users to /api/v1/.
terminalTerminalonWeb terminal tab on app detail pages
environmentsEnvironmentsonMultiple environments per app (staging, preview)
backupsBackupsonScheduled volume backups and the backups tab
cronCron JobsonScheduled cron jobs inside containers
passwordAuthPassword AuthonEmail/password sign-in and onboarding
meshInstancesonMulti-instance WireGuard mesh. Adds the Instances tab to project pages and admin settings.

Toggling a flag from the admin UI writes to system_settings and takes effect on the next request — no restart needed.

To set flags in config:

# vardo.yml
features:
  terminal: false
  environments: false
  mesh: false

Config file changes require an app container restart to take effect.

GitHub App

The GitHub App integration enables automatic deployments on push and pull request previews.

Setup

  1. Create a GitHub App in your GitHub account or organization settings.
  2. Set the webhook URL to https://your-domain.com/api/v1/github/webhook.
  3. Required permissions: Contents: read, Pull requests: read.
  4. Subscribe to events: Push, Pull request.
  5. Generate a private key and download it.

Configuration

# vardo.yml
github:
  appId: "123456"
  appSlug: "your-app-name"
  clientId: "Iv1.abc123"

# vardo.secrets.yml
github:
  clientSecret: "<client secret>"
  privateKey: "<base64-encoded PEM private key>"
  webhookSecret: "<random string used when creating the app>"

Or configure via the admin UI. Base64-encode the private key:

base64 -w 0 your-app.pem

How it works

  • Push events — Vardo finds all apps with autoDeploy=true matching the repo and branch, then triggers deployment.
  • Pull request events — Vardo creates or destroys preview environments (requires the environments feature flag). Preview URLs are posted as a PR comment.

Backup targets

System-level backup targets are available to all organizations. Org-level backup targets are managed separately under each org's settings.

Supported types: s3, r2 (Cloudflare R2), b2 (Backblaze B2), ssh, local.

Local targets can be restricted with the ALLOW_LOCAL_BACKUPS environment variable.

Domain and SSL

SettingDescription
DomainPrimary domain for the Vardo instance
Base domainWildcard subdomain base for app routing
ACME emailEmail for certificate registration

SSL is handled by Traefik using ACME. Three certificate issuers are supported:

  • Let's Encrypt (default)
  • Google Trust Services
  • ZeroSSL (with External Account Binding credentials)

Per-domain resolver selection lets you override the default issuer for specific domains.

Config

Shows the effective configuration in use — merged from vardo.yml, database settings and environment variables. Useful for verifying which setting is active.

Admins can export and import configuration via /api/v1/admin/config/export and /api/v1/admin/config/import.

Instances (mesh)

Only visible when the mesh feature flag is enabled. Manage connected Vardo instances — invite new peers, view peer status (online/offline/unreachable) and run mesh operations (clone, promote, pull).

User management

Users tab

Shows all users across the instance. Admins can:

  • View user details (email, auth methods, creation date)
  • Promote or revoke app admin status

Organizations tab

Shows all organizations. Admins can:

  • View org members and their roles
  • Access any org's settings for support and debugging

Invitations

Org owners and admins can invite users via email. Invitations have an expiration date and track status (pending, accepted, expired). The invite flow:

  1. Admin sends invite from the org's Invitations settings tab.
  2. Invitee receives an email with a unique token link.
  3. If the invitee is already logged in with a matching email, the invitation is auto-accepted.
  4. Otherwise, they create an account and join the org.

Backing up Vardo's database

Vardo's PostgreSQL data lives in a Docker volume. For production instances, set up automated backups of this volume.

Option 1: pg_dump via cron

# Daily at 2am from the host
0 2 * * * docker exec vardo-postgres pg_dump -U vardo vardo | gzip > /backups/vardo-$(date +\%Y\%m\%d).sql.gz

Option 2: volume snapshot

Most VPS providers (Hetzner, DigitalOcean, Vultr) offer volume snapshots. Schedule daily snapshots of the disk containing Docker volumes.

Restoring

# Stop the app
docker compose stop vardo-frontend

# Restore
gunzip -c backup.sql.gz | docker exec -i vardo-postgres psql -U vardo vardo

# Start the app
docker compose start vardo-frontend

Configuration files

vardo.yml is the primary config file, typically at /opt/vardo/vardo.yml. Config file values take precedence over all other sources.

# vardo.yml — safe to commit, no secrets
instance:
  id: "my-vardo"
  name: "My Vardo"
  domain: "vardo.yourdomain.com"
  baseDomain: "apps.yourdomain.com"
  serverIp: "1.2.3.4"

auth:
  registrationMode: closed   # open | closed | approval
  sessionDurationDays: 7

features:
  terminal: true
  environments: true
  backups: true
  cron: true
  mesh: true
# vardo.secrets.yml — never commit, chmod 600
encryptionKey: "<64-char hex>"
authSecret: "<random>"
acmeEmail: "[email protected]"
email:
  apiKey: "<provider api key>"
backup:
  accessKey: "<s3 key>"
  secretKey: "<s3 secret>"
github:
  clientSecret: "<secret>"
  privateKey: "<base64 pem>"
  webhookSecret: "<random>"

Changes to vardo.yml require restarting the app container to take effect.

Updating Vardo

Pull the latest image and restart:

cd /opt/vardo

# Pull latest images
docker compose pull

# Restart
docker compose up -d

# Run pending database migrations
docker compose exec vardo-frontend pnpm db:migrate

The install script's update mode automates this:

curl -fsSL https://get.vardo.sh | bash -s -- update

Health and diagnostics

Health endpoint

curl https://your-domain.com/api/health

Returns CPU, memory and disk usage with status (ok, warning, critical).

System health (admin)

The /api/v1/admin/health endpoint returns service status, runtime info, auth method configuration and feature flag states — the same data shown in the admin panel's System tab.

Docker diagnostics

From the admin panel Maintenance tab, run Docker prune to reclaim disk space from unused images, stopped containers and dangling networks.

From the host:

# Check all Vardo containers
docker ps --filter name=vardo

# View app logs
docker logs vardo-frontend --tail 100 -f

# Check resource usage
docker stats --no-stream

install.sh doctor mode

curl -fsSL https://get.vardo.sh | bash -s -- doctor

Checks Docker and Docker Compose versions, port availability (80, 443), environment variables, service health and disk space.

Traefik

Traefik runs as vardo-traefik and handles all inbound HTTP/HTTPS traffic:

  • HTTP (port 80) redirects permanently to HTTPS.
  • HTTPS (port 443) uses ACME TLS certificates.
  • Apps are routed by Traefik labels on their containers — Vardo generates these automatically when autoTraefikLabels is enabled (the default).
  • Log level defaults to WARN. Set TRAEFIK_LOG_LEVEL=DEBUG for verbose output.

Traefik's dashboard is not enabled by default. Don't enable it without authentication.

Troubleshooting

On this page