Busabase

Configuration reference

Every environment variable the self-hosted deployment reads — what it does, what happens if you get it wrong, and whether changing it needs a restart.

The all-in-one image generates most credentials on first boot and defaults APP_URL to http://localhost:3000; the Compose deployment has init.sh write your .env, and APP_URL is yours to fill in. The differences are called out below.

APP_URL is the one people get wrong. It must match the browser's address bar exactly — scheme, host and port all count. When it does not, the sign-in request is rejected with 403 Invalid origin and the UI shows Invalid origin plainly — it does not look like a successful sign-in that bounces back to the login page.

Required

VariableAll-in-one defaultComposeRestart neededWhat it does
BUSABASE_IMAGE—busabase/busabase-premium:latestyesWhich image to run. The public :latest is the same self-hosted build for trial and licensed use; pin a version tag from your own mirror if you prefer.
APP_URLhttp://localhost:3000required (init.sh asks)yesThe address users actually type, scheme and port included. Also the baseline for sign-in origin checks.
APP_PORT30003000yesHost port published for the app.
POSTGRES_USERbusabasebusabaseyesDatabase user.
POSTGRES_PASSWORDgenerated on first bootrequired (init.sh generates)yesDatabase password. Generate it, do not choose it.
POSTGRES_DBbusabasebusabaseyesDatabase name.
S3_ACCESS_KEYbusabasebusabaseyesObject-storage key. Must match seaweed-s3.json.
S3_SECRET_KEYgenerated on first bootrequired (init.sh generates)yesObject-storage secret. Must match seaweed-s3.json.
S3_BUCKETbusabasebusabaseyesBucket name; created automatically.
BETTER_AUTH_SECRETgenerated on first bootrequired (init.sh generates)yesSigns session cookies. Leaking it lets anyone forge a login.

Origins and reverse proxies

The sign-in endpoints compare the request's Origin header (scheme + host + port must match exactly) against the trusted list. Trusted origins come from:

  1. APP_URL / BETTER_AUTH_BASE_URL / NEXT_PUBLIC_APP_URL;
  2. BETTER_AUTH_ADDITIONAL_ORIGINS (a comma-separated list of origins);

Behind a reverse proxy, APP_URL must equal the address the browser actually visits — not the container's internal address. The proxy must also forward the original host and scheme: proxy_set_header Host $host; and proxy_set_header X-Forwarded-Proto $scheme;. Without those, callbacks and cookies can still go wrong even when APP_URL is set correctly.

Configure the public Origin

The all-in-one image defaults to http://localhost:3000 for local evaluation. For any IP, hostname, non-default port, or reverse proxy, set APP_URL before starting the container. Busabase never trusts an Origin merely because a request supplied it.

  • To trust several origins at once (an IP and hostname side by side, or a migration period), use BETTER_AUTH_ADDITIONAL_ORIGINS.
  • For a hostname change, configure the new Origin and restart before switching traffic.

Optional

VariableDefaultRestart neededWhat it does
BETTER_AUTH_ADDITIONAL_ORIGINSemptyyesComma-separated extra trusted origins. The only switch that trusts several addresses at once.
IMAGE_REGISTRYdocker.ioyesPull the Postgres and SeaweedFS images from an internal mirror instead.
SYSTEM_ADMIN_EMAILadmin@example.comyesWhich account gets the system admin console.
EMAIL_VERIFICATION_REQUIREDfalse (self-hosted)yesSet to true only with working mail delivery. If delivery fails, set it back to false and restart; the original administrator can then sign in.
EMAIL_PROVIDERresendyesMail provider: resend, postmark, sendgrid, or ses.
Provider credentialsemptyyesSet the matching RESEND_API_KEY, POSTMARK_SERVER_TOKEN, SENDGRID_API_KEY, or AWS credential variables.
EMAIL_FROM / EMAIL_LOGO_URLproduct defaultsyesSender identity and optional absolute logo URL used in authentication email.
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRETemptyyesBoth are required; otherwise the GitHub login button and provider are disabled.
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRETemptyyesBoth are required; otherwise the Google login button and provider are disabled.
SEAWEEDFS_VOLUME_LIMIT_MB1024yesSize at which SeaweedFS rolls to a new volume file. Raise it for large attachment estates.

Set for you

These are injected by the Compose file or the image. You do not normally set them, but knowing they exist explains behaviour you might otherwise find surprising.

VariableValueWhy
BUSABASE_EDITIONself-hostedRemoves billing, the waitlist and the public marketing pages. Read once at boot — deliberately not an admin-toggleable flag, because flipping it back would re-expose the billing surfaces.
PG_DATABASE_URLbuilt from the POSTGRES_* valuesPoint this at your own Postgres to use external infrastructure.
STORAGE_URLbuilt from the S3_* valuesOne URL rather than separate variables. minio:// means "S3, path-style, no TLS" — the protocol, not the vendor.
REDIS_URLlmdb:///data/cacheAn embedded LMDB cache with in-process pub/sub. A separate Redis buys nothing at single-replica scale, and Redis 7.4+ is RSALv2/SSPL, which carries redistribution constraints we would rather not pass on to you.

Every variable here needs a restart to take effect. There is no runtime reload: the values are read at boot, which is what makes a running instance's configuration reproducible from its .env alone.

Generated, not configured

The all-in-one image generates its own Postgres password, object-storage keys and session secret on first boot and writes them to /data/.credentials with mode 600. They are not in the image, so two people pulling the same image do not share secrets.

Back that file up. It is the only copy.

On this page