Skip to guide
Deployment/Get started
Self-hosting reference

Production with Compose

Use the production overlay for a public instance with TLS, private service ports, and a persistent worker.

Prepare the host and domains

Use a current Docker Compose plugin that supports !reset (2.24.4 or newer). Point DOMAIN, files.DOMAIN, and home.DOMAIN at the server. The supplied Caddy configuration sends the product to app:3000, /api/inngest to worker:8020, files to SeaweedFS, and the public site to landing:3001.

.env · example public origins and cloud OCR
DOMAIN=workspace.example.com
ACME_EMAIL=ops@example.com
BETTER_AUTH_URL=https://workspace.example.com
APP_PUBLIC_URL=https://workspace.example.com
OCR_DEFAULT_PROVIDER=AZURE
AZURE_DOC_INTELLIGENCE_ENDPOINT=https://your-resource.cognitiveservices.azure.com
AZURE_DOC_INTELLIGENCE_KEY=replace-with-your-resource-key
CONVERTER_ALLOWED_FETCH_ORIGINS=https://workspace.example.com,https://files.workspace.example.com
ADEU_ALLOWED_FETCH_ORIGINS=https://workspace.example.com,https://files.workspace.example.com

Replace the local defaults for database, storage, auth, file tokens, and all service credentials. Keep EMBEDDING_SECRETS_KEY stable: it protects stored provider credentials and OAuth grants.

Forward settings to both processes

Compose uses an explicit environment allowlist. A value in .env reaches a container only if that service forwards it. Add an operator override for settings absent from the base file, including APP_PUBLIC_URL and any OAuth or feature flags you enable.

docker-compose.operator.yml
services:
  app:
    environment: &operator-env
      APP_PUBLIC_URL: ${APP_PUBLIC_URL:?Set the public app origin}
  worker:
    environment: *operator-env

Add provider client IDs, secrets, and feature flags to this shared block when enabling connections or optional capabilities. Existing base values are retained by the Compose merge.

Build the public site for your origins

NEXT_PUBLIC_* variables are bundled at build time. The current landing Dockerfile does not consume build arguments for its origins; runtime environment entries in the production overlay cannot rewrite account links already in the browser bundle. Add the following to its builder stage before the build command, then pass matching build.args on the landing service.

apps/landing/Dockerfile · builder stage
ARG NEXT_PUBLIC_SITE_URL
ARG NEXT_PUBLIC_APP_URL
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL

Set landing build arguments

Extend the same operator override with the landing service below. Use the same origins for the build and runtime settings.

docker-compose.operator.yml · under services
  landing:
    build:
      args:
        NEXT_PUBLIC_SITE_URL: https://home.${DOMAIN}
        NEXT_PUBLIC_APP_URL: https://${DOMAIN}

Start and check the merged stack

The overlay uses published app and worker images; migrations still build from your checkout. For repeatable releases, pin both images to a tested release or digest and use a matching source checkout for migrations and model configuration. Preview the merged service names, then start.

Terminal
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.operator.yml --env-file .env config --services
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.operator.yml --env-file .env up --build -d
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.operator.yml logs --tail=100 migrate app worker caddy

The lean overlay disables local Whisper and the Inngest dev server. Configure cloud transcription and OCR, or explicitly enable the relevant profiles. The supplied files hostname serves objects anonymously by URL; choose storage and access controls that fit your deployment.

Deployment Guide — Self-Host Launchstack | Launchstack