Skip to content
flexcal Documentation

Configuration

Configuration is entirely environment-driven. .env.example in the repository root is the authoritative list; the tables below cover the variables that matter most for a self-hosted instance.

These must be present when the app starts.

Variable Description Required Default
DATABASE_URL Database URL with credentials. If you use a connection pooler, point this at the pooler. required postgresql://unicorn_user:magical_password@database:5432/calendso
NEXT_PUBLIC_WEBAPP_URL Base URL of the site. The image ships a placeholder in its statically built files, which is rewritten to this value the first time the container starts. optional http://localhost:3000
NEXTAUTH_URL Location of the auth server. Defaults to the flexcal instance itself. optional {NEXT_PUBLIC_WEBAPP_URL}/api/auth
NEXTAUTH_SECRET Cookie encryption key. Must match the build-time value. Generate with openssl rand -base64 32. required secret
CALENDSO_ENCRYPTION_KEY Authentication encryption key, 32 bytes for AES256. Must match the build-time value. Generate with openssl rand -base64 24. required secret
SKIP_DB_MIGRATIONS Set to 1 to stop the container applying migrations on start. Leave unset for Docker Compose, which has nowhere else to run them. Set it when the deployment migrates once per release, otherwise every replica races the others. optional unset
SKIP_APP_STORE_SEED Set to 1 to stop the container seeding the app store on start. Same reasoning as SKIP_DB_MIGRATIONS; the seed costs roughly 8s of every pod’s startup. optional unset
NEXT_PUBLIC_VAPID_PUBLIC_KEY Web push public key, generated with npx web-push generate-vapid-keys. required for push unset
VAPID_PRIVATE_KEY Web push private key from the same key pair. required for push unset
DATABASE_SCHEMA Schema that Prisma resolves unqualified objects against. Appended to DATABASE_URL and DATABASE_DIRECT_URL as schema= when neither already names one, so an explicit schema= in the URL always wins. Only change this if the deployment genuinely keeps flexcal’s tables outside public. optional public

Prisma only issues SET search_path when the connection URL carries a schema= argument. Without one, the session keeps the PostgreSQL default of "$user", public, so on a deployment where the database role owns a schema of the same name, unqualified CREATE TABLE / CREATE TYPE in a migration lands in that role schema rather than in public. Prisma then looks in public, finds nothing, and the application keeps working only by search_path accident: a connection using a different role or search_path breaks.

Setups where the role owns a same-named schema include Crunchy PostgreSQL Operator with autoCreateUserSchema, Supabase, and any database where someone created a schema named after the login role.

The container handles this for you: scripts/start.sh pins the schema before touching the database.

Databases that already have stranded objects are repaired by the 20260818120000_relocate_shadow_schema_objects migration, which moves them back into public. It reports a warning and changes nothing where public already holds an object of the same name.

These are baked in when the image or the app is built. Changing them means rebuilding.

Variable Description Required Default
DATABASE_URL Only needs to be parseable at build time; no connection is made. required postgresql://unicorn_user:magical_password@database:5432/calendso
MAX_OLD_SPACE_SIZE Node.js heap size for the build, in MB. optional 6144
NEXTAUTH_SECRET Cookie encryption key. required secret
CALENDSO_ENCRYPTION_KEY Authentication encryption key. required secret
NEXT_PUBLIC_WEBAPP_URL Default base URL for the built image; a deployment overrides it with the run-time variable of the same name. optional http://localhost:3000
NEXT_PUBLIC_WEBSITE_TERMS_URL Custom URL for the terms and conditions page. optional
NEXT_PUBLIC_WEBSITE_PRIVACY_POLICY_URL Custom URL for the privacy policy page. optional
NEXT_PUBLIC_CALCOM_VERSION Version string rendered in the footer; unset renders dev. optional
CSP_POLICY Content Security Policy mode, see below. optional
CALCOM_TELEMETRY_DISABLED Set to 1 to disable anonymous usage telemetry. optional

Set CSP_POLICY="non-strict" to enable Strict CSP with the exception of unsafe-inline in style-src. Custom changes to an instance may need adjusting to stay CSP-compatible.

Strict CSP is currently enforced only on the login page. Other server-rendered pages run it in report-only mode to surface problems. Statically generated pages are not covered yet.

NEXT_PUBLIC_LOGGER_LEVEL controls verbosity for all tRPC queries and mutations. The level you set is the minimum that gets logged:

Value Level
0 silly
1 trace
2 debug
3 info
4 warn
5 error
6 fatal
Terminal window
echo 'NEXT_PUBLIC_LOGGER_LEVEL=3' >> .env

Third-party integrations read their credentials from .env and .env.appStore. See the Apps section for the per-provider setup.