Vardo

Configuration

Environment variables, vardo.yml config-as-code, feature flags, and template format reference.

Vardo uses a layered configuration system. Settings resolve in this order:

  1. vardo.yml (and vardo.secrets.yml) — highest priority, overrides everything
  2. DB system_settings — set via the admin UI, stored encrypted in PostgreSQL
  3. Hardcoded defaults — sensible values that work out of the box

Only a handful of environment variables remain as infrastructure connections. Everything else — email, GitHub, feature flags, instance name — is managed via config files or the admin UI.

Environment variables

Copy .env.example to .env and fill in the values. The install script generates .env automatically for production.

Core (required)

VariableDescriptionDefault
DATABASE_URLPostgreSQL connection stringpostgresql://host:host@localhost:7100/host
REDIS_URLRedis connection stringredis://localhost:7200
BETTER_AUTH_SECRETSecret key for session signing and encryptionvardo-dev-secret-change-in-production
NEXT_PUBLIC_BETTER_AUTH_URLPublic URL of the Vardo instancehttp://localhost:3000
NEXT_PUBLIC_APP_URLPublic URL of the Vardo instance (used by the frontend)http://localhost:3000

Encryption (required)

VariableDescription
ENCRYPTION_MASTER_KEY256-bit hex key for encrypting secrets (env vars, deploy keys, system settings). Generate with openssl rand -hex 32.

Instance identity

VariableDescriptionDefault
VARDO_DOMAINDashboard domain (production only)localhost
VARDO_INSTANCE_IDUnique identifier for this instance (used in mesh networking)--
VARDO_PROJECTS_DIRDirectory for deployment data./.host/projects (dev), /var/lib/host/projects (prod)
VARDO_CONFIG_DIRDirectory where vardo.yml is read fromcwd

TLS (production)

VariableDescription
ACME_EMAILEmail for Let's Encrypt certificate registration
ZEROSSL_EAB_KIDZeroSSL External Account Binding key ID
ZEROSSL_EAB_HMACZeroSSL External Account Binding HMAC

Provider restrictions (optional)

These environment variables control which provider types are allowed on the instance. All default to true if unset.

VariableDescriptionDefault
ALLOW_SMTPAllow SMTP as an email provider. Set to false to restrict to API-based providers (Mailpace, Resend, Postmark).true
ALLOW_LOCAL_BACKUPSAllow local/SSH backup targets. Set to false to require cloud storage (S3, R2, B2).true
ALLOW_PASSWORD_AUTHAllow email/password authentication. Set to false to enforce passkey, magic link or OAuth only. Works alongside the passwordAuth feature flag — both must be enabled for password auth to work.true

Analytics (optional)

VariableDescription
NEXT_PUBLIC_PLAUSIBLE_DOMAINDomain for Plausible analytics tracking
NEXT_PUBLIC_PLAUSIBLE_SRCPlausible analytics script URL

vardo.yml — config as code

Place a vardo.yml file in your Vardo install directory (or wherever VARDO_CONFIG_DIR points) to configure system settings as code. This file takes priority over anything in the DB.

For secrets (API keys, passwords, private keys), use a separate vardo.secrets.yml file. It gets 0600 permissions automatically. The vardo.yml file is safe to version-control; the secrets file isn't.

File layout

vardo.yml
vardo.secrets.yml
.env
docker-compose.yml

vardo.yml structure

instance:
  name: "My Vardo"
  domain: "host.example.com"
  baseDomain: "example.com"
  serverIp: "1.2.3.4"

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

email:
  provider: mailpace          # smtp | mailpace | resend | postmark
  fromEmail: [email protected]
  fromName: Vardo

backup:
  type: s3                    # s3 | r2 | b2 | ssh
  bucket: my-backups
  region: us-east-1
  endpoint: https://s3.amazonaws.com  # optional, for S3-compatible providers

github:
  appId: "12345"
  appSlug: my-vardo-app
  clientId: Iv1.abc123

features:
  mesh: true
  passwordAuth: false

vardo.secrets.yml structure

encryptionKey: "..."       # ENCRYPTION_MASTER_KEY equivalent
authSecret: "..."          # BETTER_AUTH_SECRET equivalent
acmeEmail: [email protected]

email:
  apiKey: "..."            # Mailpace or Resend API key
  smtpPass: "..."          # SMTP password (if provider is smtp)

backup:
  accessKey: "..."
  secretKey: "..."

github:
  clientSecret: "..."
  privateKey: "..."        # PEM private key (base64 ok)
  webhookSecret: "..."

How config gets imported

On startup, Vardo reads vardo.yml and vardo.secrets.yml and merges them. The merged config takes priority over all DB system_settings. You can also import a config file into the DB via the admin UI — this copies all sections into system_settings, making them editable through the UI while the file is removed.

Config is cached in memory for 30 seconds. Changes to the files take effect within one cache TTL.

AES-256-GCM encryption

Sensitive settings stored in the database (env vars, deploy keys, system settings) are encrypted at rest using AES-256-GCM. The ENCRYPTION_MASTER_KEY env var provides the key material.

Feature flags

Feature flags control which capabilities are available system-wide. All flags default to enabled. Set a flag to false in vardo.yml (under features:) or toggle it in the admin UI.

Resolution: vardo.yml > DB system_settings > default (true).

Core features — projects, apps, deployments — can't be disabled. Metrics and logs are always available.

FlagKeyDescription
Web UIuiWeb dashboard. Disabling leaves only the API accessible.
TerminalterminalWeb-based shell access to running containers. Removes the Terminal tab when disabled.
EnvironmentsenvironmentsMultiple deployment environments per app (staging, preview). Disabled = production only.
BackupsbackupsScheduled volume snapshots to S3-compatible storage. Also required for mesh volume transfers.
Cron JobscronScheduled command execution inside containers. Removes the Cron tab when disabled.
Password AuthpasswordAuthEmail/password sign-in. Disabled = passkey, magic link or GitHub only.
Instances (Mesh)meshConnect multiple Vardo instances over encrypted WireGuard tunnels.

Feature flags gate both UI tabs and their corresponding API endpoints.

Example — enforce passkey/OAuth only

features:
  passwordAuth: false

Template format

Templates are TOML files in the templates/ directory. Each file defines a deployable service with sensible defaults.

Example: PostgreSQL

version = "1"
name = "postgres"
displayName = "PostgreSQL"
description = "Powerful open-source relational database"
icon = "https://cdn.simpleicons.org/postgresql/4169E1"
category = "database"
source = "direct"
deployType = "image"
imageName = "postgres:16"
defaultPort = 5432

[[envVars]]
key = "POSTGRES_PASSWORD"
description = "Superuser password"
required = true

[[envVars]]
key = "POSTGRES_USER"
description = "Superuser name"
required = false
defaultValue = "postgres"

[[envVars]]
key = "POSTGRES_DB"
description = "Default database name"
required = false
defaultValue = "postgres"

[[volumes]]
name = "data"
mountPath = "/var/lib/postgresql/data"
description = "PostgreSQL data files"

[[connectionInfo]]
label = "Connection URL"
value = "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${project.name}:5432/${POSTGRES_DB}"

Template fields

FieldTypeDescription
versionstringTemplate format version
namestringUnique identifier (filename without .toml)
displayNamestringHuman-readable name
descriptionstringShort description
iconstringIcon URL
categorystringOne of: database, cache, monitoring, web, tool, custom
sourcestringdirect or git
deployTypestringimage, compose, dockerfile, nixpacks, railpack, static
imageNamestringDocker image (for image deploy type)
gitUrlstringGit repository URL (for git source)
gitBranchstringGit branch
composeContentstringInline compose file content
rootDirectorystringSubdirectory in the repository
defaultPortintegerDefault container port

[[envVars]] — default environment variables

FieldTypeDescription
keystringVariable name
descriptionstringHuman-readable description
requiredbooleanWhether the user must provide a value
defaultValuestringDefault value if not required

[[volumes]] — default persistent volumes

FieldTypeDescription
namestringVolume name suffix
mountPathstringMount path inside the container
descriptionstringHuman-readable description

[[connectionInfo]] — connection metadata

Shown in the app's Connect tab after deployment.

FieldTypeDescription
labelstringDisplay label (e.g. "Port", "Connection URL")
valuestringValue, supports ${...} template expressions
copyRefstringOptional env var name for the copy button

Docker Compose profiles

The dev environment uses docker-compose.override.yml to customize the stack:

  • The host service is disabled (use pnpm dev for hot reload instead)
  • PostgreSQL exposed on port 7100
  • Redis exposed on port 7200
  • cAdvisor exposed on port 7300
  • Loki exposed on port 7400
  • Traefik runs with an insecure dashboard on port 8080 (no TLS, no BasicAuth)

In production, the base docker-compose.yml runs with --env-file .env. All services communicate over the internal vardo-network Docker network and only Traefik exposes ports 80 and 443 to the host.

On this page