Skip to content

Self-Host Config Reference

Most self-hosted solo installs do not need this page. The normal path is still:

  • set DOMAIN
  • set OPENROUTER_API_KEY
  • let the installer generate the secrets and local bucket credentials

This page is for the larger set of optional envs that still appear in the published Docker Compose bundle.

These are the main envs for a normal solo install:

DOMAIN=https://example.com
OPENROUTER_API_KEY=sk-or-v1-...
STUDIO_MACHINE_PROVIDER=docker
VIVD_CADDY_TLS_MODE=managed
OPENCODE_MODEL_STANDARD=openrouter/google/gemini-3-flash-preview
OPENCODE_MODEL_ADVANCED=openrouter/google/gemini-3.1-pro-preview
VIVD_SCRATCH_CREATION_MODE=studio_astro

If you are not using install.sh, you must also provide:

BETTER_AUTH_SECRET=...
POSTGRES_USER=postgres
POSTGRES_PASSWORD=...
POSTGRES_DB=vivd
SCRAPER_API_KEY=...
VIVD_LOCAL_S3_ACCESS_KEY=...
VIVD_LOCAL_S3_SECRET_KEY=...

These are advanced overrides. Most solo installs can leave them unset and use DOMAIN plus the Instance Settings -> Network UI later.

# Force the canonical public app origin explicitly
VIVD_APP_URL=https://example.com

# Legacy auth/public-origin override
BETTER_AUTH_URL=https://example.com

# Advanced host override when admin lives on another host
CONTROL_PLANE_HOST=app.example.com

# Additional trusted or admin-only hosts
SUPERADMIN_HOSTS=app.example.com
TRUSTED_DOMAINS=preview.example.com

# Bundled Caddy TLS controls
# managed  = bundled Caddy gets and renews certificates
# external = another proxy handles TLS; keep the public origin on https
# off      = plain HTTP only
VIVD_CADDY_TLS_MODE=managed
VIVD_CADDY_ACME_EMAIL=admin@example.com
VIVD_PUBLISH_INCLUDE_WWW_ALIAS=false

# Optional override for bundled self-host Caddyfile rewrites from Instance Settings -> Network
# default: true on solo installs, false on platform installs
# set false to disable it on solo, or true to force-enable it elsewhere
VIVD_SELFHOST_CADDY_UI_MANAGED=true

For the admin-side meaning of those settings, read Instance Settings.

Start with one provider plus VIVD_EMAIL_FROM.

VIVD_EMAIL_PROVIDER=smtp
VIVD_EMAIL_FROM=noreply@example.com

SMTP:

VIVD_SMTP_HOST=smtp.example.com
VIVD_SMTP_PORT=587
VIVD_SMTP_USER=your-user
VIVD_SMTP_PASSWORD=your-password
VIVD_SMTP_SECURE=false

Alternative SMTP shortcut:

VIVD_SMTP_URL=smtps://user:pass@smtp.example.com:465

Resend:

VIVD_EMAIL_PROVIDER=resend
RESEND_API_KEY=re_xxx
RESEND_WEBHOOK_SECRET=whsec_xxx

SES:

VIVD_EMAIL_PROVIDER=ses
VIVD_SES_REGION=eu-central-1
VIVD_SES_ACCESS_KEY_ID=...
VIVD_SES_SECRET_ACCESS_KEY=...
VIVD_SES_FROM_EMAIL=noreply@example.com

Optional transactional email identity/footer bootstrap:

VIVD_EMAIL_BRAND_DISPLAY_NAME=Example Studio
VIVD_EMAIL_BRAND_SUPPORT_EMAIL=support@example.com
VIVD_EMAIL_BRAND_WEBSITE_URL=https://example.com
VIVD_EMAIL_BRAND_IMPRINT_URL=https://example.com/imprint
VIVD_EMAIL_BRAND_PRIVACY_URL=https://example.com/privacy

For provider behavior, webhooks, and deliverability workflows, read Email & Deliverability.

The hosted self-host bundle defaults to the bundled local S3-compatible bucket:

VIVD_BUCKET_MODE=local
VIVD_LOCAL_S3_ACCESS_KEY=...
VIVD_LOCAL_S3_SECRET_KEY=...

In bundled local mode, Vivd infers these internal defaults unless you override them manually:

VIVD_LOCAL_S3_BUCKET=vivd
VIVD_LOCAL_S3_ENDPOINT_URL=http://minio:9000
VIVD_LOCAL_S3_REGION=us-east-1
VIVD_LOCAL_S3_DOWNLOAD_ENDPOINT_URL=<public-origin>/_vivd_s3

Treat those as advanced overrides for custom local-storage topologies. The inline minimal self-host example omits them on purpose.

To switch later to an external S3-compatible bucket:

VIVD_BUCKET_MODE=external
VIVD_S3_BUCKET=vivd
VIVD_S3_ENDPOINT_URL=https://s3.example.com
VIVD_S3_ACCESS_KEY_ID=...
VIVD_S3_SECRET_ACCESS_KEY=...
VIVD_S3_REGION=us-east-1

Optional storage extras:

VIVD_S3_PUBLIC_BASE_URL=https://cdn.example.com
VIVD_S3_DOWNLOAD_ENDPOINT_URL=https://objects.example.com
VIVD_S3_SESSION_TOKEN=...

R2 compatibility aliases still work:

R2_BUCKET=vivd
R2_ENDPOINT=https://<accountid>.r2.cloudflarestorage.com
R2_ACCESS_KEY=...
R2_SECRET_KEY=...

Cloudflare Turnstile automation:

CLOUDFLARE_ACCOUNT_ID=...
CLOUDFLARE_API_TOKEN=...

GitHub backup/sync:

GITHUB_SYNC_ENABLED=true
GITHUB_ORG=your-github-org
GITHUB_TOKEN=ghp_xxx

External scraper service:

SCRAPER_URL=https://scraper.example.com
SCRAPER_API_KEY=...

Optional thumbnail-preview base override for advanced scraper topologies:

VIVD_THUMBNAIL_PREVIEW_BASE_URL=https://app.example.com

The bundled self-host Docker stack infers this automatically and usually does not need it. Set it only when thumbnails should fetch preview pages from a different internal or public origin than the default.

Optional residential proxy for the bundled scraper’s Puppeteer browser. This is mainly useful when website import fails because the target site blocks datacenter IPs or serves Cloudflare / human-verification pages to automated traffic:

PROXY_HOST=proxy.example.com
PROXY_PORT=823
PROXY_USERNAME=...
PROXY_PASSWORD=...

Set PROXY_HOST to enable it. PROXY_PORT defaults to 823. Credentials are only used when both username and password are present. This is an install-level setting for the bundled scraper service in the published Compose bundle, not a per-project import option. If you run a separate external scraper via SCRAPER_URL, configure the proxy on that scraper deployment instead.

Optional OpenCode model overrides:

OPENCODE_MODEL_STANDARD=openrouter/google/gemini-3-flash-preview
OPENCODE_MODEL_ADVANCED=openrouter/google/gemini-3.1-pro-preview
OPENCODE_MODEL_PRO=openrouter/google/gemini-3.1-pro-preview

Scratch creation mode defaults to studio_astro. Switch back to legacy_html only if you intentionally want the older backend-generated plain HTML flow:

VIVD_SCRATCH_CREATION_MODE=legacy_html

Optional scratch-generation model overrides for the legacy backend HTML flow:

VIVD_GENERATION_MODEL=google/gemini-3.1-pro-preview
VIVD_ANALYSIS_MODEL=google/gemini-3.1-pro-preview
VIVD_HERO_GENERATION_MODEL=google/gemini-3-pro-image-preview
VIVD_IMAGE_EDITING_MODEL=google/gemini-3-pro-image-preview

Optional Vertex-based configuration:

GOOGLE_CLOUD_PROJECT=your-gcp-project
VERTEX_LOCATION=global
GOOGLE_APPLICATION_CREDENTIALS_JSON='{"type":"service_account",...}'

Optional Docker Studio tuning:

DOCKER_STUDIO_CPUS=1
# Optional explicit override. Leave unset to use Vivd's auto-sized default.
DOCKER_STUDIO_MEMORY_MB=2560
DOCKER_STUDIO_MEMORY_AUTO_RESERVE_MB=1536
DOCKER_STUDIO_MEMORY_AUTO_MIN_MB=2048
DOCKER_STUDIO_MEMORY_AUTO_MAX_MB=3072
DOCKER_STUDIO_NETWORK=vivd-network
DOCKER_STUDIO_ROUTE_PREFIX=/_studio
DOCKER_STUDIO_IMAGE=ghcr.io/vivd-studio/vivd-studio:latest

If DOCKER_STUDIO_MEMORY_MB is unset, Vivd auto-sizes Docker-managed Studio RAM from the detected host or cgroup memory budget, subtracts a default 1536 MiB reserve for the rest of the stack, and clamps the result to 2048-3072 MiB. On a 4 GiB host that yields 2560 MiB by default.

  • This reference is intentionally scoped to the self-hosted solo bundle.
  • The root .env.example in the repo is broader because it also covers local dev and platform/SaaS paths.
  • If an env is not mentioned here, check whether it is really needed for your install before adding it.