Configuration reference
This page is generated from docker/settings.json, the registry of every setting. A check (npm run docs:check-settings) fails when the registry and docker/entrypoint.sh, docker/Dockerfile, docker/compose.yaml or the source files that read build-time variables disagree.
Container settings
The container reads these environment variables at start-up. Nothing deployment-specific is baked into the image.
- Every variable can also be read from a file: set
NAME_FILE=/pathinstead ofNAME(Docker or Kubernetes secrets). Setting both stops the container. Trailing newlines in the file are removed. - An empty value counts as unset, so the default applies.
- Each value is checked against the pattern shown. On an invalid value the container logs
sidedoc-entrypoint: ERROR: ...and exits with code 64 (see Troubleshooting). - None of these values is secret. They end up in public response headers or in
/config.js, which every visitor downloads. - Patterns are extended regular expressions that must match the whole value.
A commented example for docker run --env-file is in docker/sidedoc.env.example.
Network
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_PORT | 8080 | 1024 to 65535 pattern [0-9]{2,5} | Port nginx listens on inside the container. Must be unprivileged, because the container runs as uid 101. | 8080 |
SIDEDOC_LISTEN_IPV6 | auto | auto, true, false | Also listen on [::]. auto enables it only when the kernel has IPv6 (/proc/net/if_inet6 exists). Booleans also accept 1/0, yes/no, on/off. | false |
SIDEDOC_REAL_IP_FROM | empty | space-separated IPv4/IPv6 addresses or CIDRs pattern [0-9A-Fa-f.:]+(/[0-9]{1,3})? | Reverse proxies whose X-Forwarded-For header is trusted. The client address in the access log then comes from that header. Empty: the address of the direct peer is logged. | 10.0.0.0/8 fd00::/8 |
nginx
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_WORKER_PROCESSES | auto | auto or 1 to 99pattern auto|[1-9][0-9]? | nginx worker_processes. auto uses one per CPU the container can see; set a number when a CPU limit is lower than the host CPU count. | 2 |
Logging
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_LOG_LEVEL | warn | debug, info, notice, warn, error, crit | nginx error log level. The error log goes to stderr. | info |
SIDEDOC_ACCESS_LOG | json | json, combined, off | Access log on stdout. json writes one object per request with time, client address, method, path (without query string), status, bytes, duration, host and request id. combined is the standard nginx format, which includes query string, referrer and user agent. | combined |
Security headers
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_CSP_FRAME_ANCESTORS | 'self' | CSP source list: hosts, schemes and quoted keywords pattern [A-Za-z0-9*.:/_'-]+( [A-Za-z0-9*.:/_'-]+)* | CSP frame-ancestors: which sites may embed SideDoc in a frame. 'self' also sends X-Frame-Options: SAMEORIGIN, 'none' sends X-Frame-Options: DENY; any other value sends no X-Frame-Options. Keywords need their single quotes: unquoted self is accepted but means a host called self. | 'self' https://portal.example.org |
SIDEDOC_CSP_CONNECT_SRC | empty | CSP source list: hosts, schemes and quoted keywords pattern [A-Za-z0-9*.:/_'-]+( [A-Za-z0-9*.:/_'-]+)* | Extra CSP connect-src sources, added after 'self'. Needed when the browser has to reach another origin, for example an S3 endpoint. | https://s3.example.org |
SIDEDOC_HSTS_MAX_AGE | 0 | 0 to 999999999 seconds pattern [0-9]{1,9} | Strict-Transport-Security max-age, with includeSubDomains. 0 sends no HSTS header. Set it only when the site and all its subdomains are HTTPS-only. Often the TLS proxy sets HSTS instead. | 31536000 |
Schemas
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_SCHEMA_VERSION | build default (see Schemas) | dotted version that is bundled under /schemas/<version>/pattern [0-9]+(\.[0-9]+){0,3} | Datamodel version new documents are created with. The image must contain schemas/<version>/; the container refuses to start otherwise. Empty: the version the app was built with. | 0.2.2 |
SIDEDOC_MIN_SUPPORTED_SCHEMA_VERSION | build default (0.0.0) | dotted version pattern [0-9]+(\.[0-9]+){0,3} | Documents with an older datamodel version open read-only and must be converted before editing. Empty: the build default, 0.0.0, so everything is editable. | 0.2.0 |
Error reporting (Sentry)
| Variable | Default | Allowed | Description | Example |
|---|---|---|---|---|
SIDEDOC_SENTRY_ENABLED | false | true, false | Browser error reporting. Off by default, so a deployment makes no third-party connections. When on, browsers post events to the same-origin path ./monitoring/envelope and nginx forwards them to the project in the DSN. | true |
SIDEDOC_SENTRY_DSN | empty | https://<hex key>@<host>[:port]/<numeric project id>pattern https://[0-9a-f]+@[A-Za-z0-9.-]+(:[0-9]{1,5})?/[0-9]+ | Sentry DSN. Required when SIDEDOC_SENTRY_ENABLED=true, ignored otherwise. The DSN is public by design (it ends up in /config.js). | https://0123abcd@o123456.ingest.de.sentry.io/4567 |
SIDEDOC_SENTRY_ENVIRONMENT | production | 1 to 64 of A-Z a-z 0-9 . _ -pattern [A-Za-z0-9._-]{1,64} | Sentry environment tag. Checked only when Sentry is enabled. | staging |
SIDEDOC_SENTRY_RELEASE | image version (SIDEDOC_VERSION) | 1 to 128 of A-Z a-z 0-9 . _ + @ -pattern [A-Za-z0-9._+@-]{1,128} | Sentry release tag. Checked only when Sentry is enabled. | sidedoc@0.6.1 |
SIDEDOC_SENTRY_TRACES_SAMPLE_RATE | 0 | 0 to 1, at most 6 decimals pattern 0|1|0?\.[0-9]{1,6}|1\.0+ | Fraction of page loads that send performance traces. Checked only when Sentry is enabled. | 0.1 |
Image
Set in the image by the Dockerfile.
| Variable | Value | Description |
|---|---|---|
SIDEDOC_VERSION | value of the VERSION build argument | Version of the image. Used as the default for SIDEDOC_SENTRY_RELEASE. Do not override it. |
Build arguments
Passed with docker buildx build --build-arg NAME=value.
| Argument | Default | Description |
|---|---|---|
NODE_IMAGE | node:22.23.3-alpine3.24 | Base image of the build stage. Pin by digest for releases. |
NGINX_IMAGE | nginxinc/nginx-unprivileged:1.30.6-alpine3.24-slim | Base image of the runtime stage. Pin by digest for releases. |
VERSION | 0.0.0-dev | Image version: OCI label org.opencontainers.image.version and SIDEDOC_VERSION. |
REVISION | unknown | Source revision (git commit) for the OCI label org.opencontainers.image.revision. |
CREATED | unknown | Build timestamp (RFC 3339) for the OCI label org.opencontainers.image.created. |
Compose variables
Interpolated by docker compose in docker/compose.yaml, from the shell or a .env file next to it.
| Variable | Default | Description |
|---|---|---|
SIDEDOC_IMAGE | sidedoc:dev | Image to run (and the tag a --build produces). |
SIDEDOC_VERSION | 0.0.0-dev | Passed as the VERSION build argument. |
Build-time variables
These apply when you build SideDoc from source (see Static hosting). The container ignores them: its build passes none of them, and the run-time settings above cover what varies between deployments.
Build from source
Environment of the build commands.
| Variable | Default | Description | Read in |
|---|---|---|---|
SIDEDOC_SCHEMAS_DIR | schemas/ next to the repository root | Path to a checkout of the schemas repository. Needed by npm run build (the backend prebuild step regenerates committed vocabulary and DCAT mapping JSON from it), by npm test, and by npm run sync:vocab -w sidedoc-frontend. Not needed for npm run dev, typecheck, the frontend tests, vite build, the image build or scripts/build-static.sh, which use the committed copies. | sidedoc-backend/scripts/build-materialized-vocab-index.mjssidedoc-backend/scripts/sync-dcat-mappings.mjssidedoc-frontend/scripts/sync-vocab.mjs |
SIDEDOC_CSP_META | true | Embed the Content-Security-Policy as a <meta> tag in the built HTML. The image build sets false and sends the policy as a header instead. Set false when your web server sends its own CSP header, because a <meta> policy and a header policy are both enforced. The <meta> policy allows connect-src to the site itself and Sentry only, so it also blocks S3 endpoints. | sidedoc-frontend/vite.config.ts |
SIDEDOC_SCHEMA_DIR | ../../Schemas relative to the frontend | Schemas checkout for the legacy npm run build:combined-dist -w sidedoc-frontend script only. Use SIDEDOC_SCHEMAS_DIR everywhere else. | sidedoc-frontend/scripts/build-combined-dist.mjs |
Frontend (Vite)
Read from the environment or app/sidedoc-frontend/.env* when Vite builds the app, and baked into the bundle. Values in config.js (window.__SIDEDOC_CONFIG__, same key names) take priority at run time. Every VITE_* value is public: never put a secret in one.
Example file: app/sidedoc-frontend/.env.example.
| Variable | Default | Description | Container setting | Read in |
|---|---|---|---|---|
VITE_SCHEMA_VERSION | 0.2.2 | Datamodel version new documents use. | SIDEDOC_SCHEMA_VERSION | sidedoc-frontend/src/config/schemaVersion.ts |
VITE_MIN_SUPPORTED_SCHEMA_VERSION | 0.0.0 | Documents below this version open read-only. | SIDEDOC_MIN_SUPPORTED_SCHEMA_VERSION | sidedoc-frontend/src/config/schemaVersion.ts |
VITE_SENTRY_ENABLED | true in production builds, false in the dev server | Browser error reporting. A production build from source reports errors unless this is false (or config.js sets it to "false"). | SIDEDOC_SENTRY_ENABLED | sidedoc-frontend/src/services/sentry.ts |
VITE_SENTRY_DSN | SideDoc's own Sentry project | Sentry DSN. Set your own, or disable Sentry, when you host SideDoc yourself. | SIDEDOC_SENTRY_DSN | sidedoc-frontend/src/services/sentry.ts |
VITE_SENTRY_TUNNEL | /monitoring/envelope | Path the browser posts events to. Your web server must proxy it to Sentry (see Static hosting). Empty string: send directly to the ingest host, which the default CSP allows only for *.ingest.sentry.io and *.ingest.de.sentry.io. | sidedoc-frontend/src/services/sentry.ts | |
VITE_SENTRY_ENVIRONMENT | Vite mode (standalone, app, ...) | Sentry environment tag. | SIDEDOC_SENTRY_ENVIRONMENT | sidedoc-frontend/src/services/sentry.ts |
VITE_SENTRY_RELEASE | build timestamp | Sentry release tag. Also the release name for source-map upload when SENTRY_RELEASE is not set. | SIDEDOC_SENTRY_RELEASE | sidedoc-frontend/src/services/sentry.tssidedoc-frontend/vite.config.ts |
VITE_SENTRY_TRACES_SAMPLE_RATE | 0.1 | Fraction of page loads that send performance traces. | SIDEDOC_SENTRY_TRACES_SAMPLE_RATE | sidedoc-frontend/src/services/sentry.ts |
VITE_SCHEMA_URL | https://sidedoc.app/schemas/0.1.0/datasheet.json | Workspace app build (--mode app) only: datasheet schema to load. | sidedoc-frontend/src/components/backend-demo/useWorkspaceLifecycleActions.ts | |
VITE_TYPE_LIBRARY_URL | https://sidedoc.app/schemas/0.1.0/type-library.json | Workspace app build (--mode app) only: type library to load. | sidedoc-frontend/src/components/backend-demo/useWorkspaceLifecycleActions.ts |
Sentry source-map upload
Read by vite.config.ts in the build process only. When org, project and token are all set, the build uploads source maps to Sentry and deletes them from dist/. The image build never passes these.
Example file: app/sidedoc-frontend/.env.example.
| Variable | Default | Description | Read in |
|---|---|---|---|
SENTRY_ORGVITE_SENTRY_ORG (alias) | empty | Sentry organisation slug. | sidedoc-frontend/vite.config.ts |
SENTRY_PROJECTVITE_SENTRY_PROJECT (alias) | empty | Sentry project slug. | sidedoc-frontend/vite.config.ts |
SENTRY_AUTH_TOKENVITE_SENTRY_AUTH_TOKEN (alias) | empty | Secret. Sentry auth token with release and source-map scope. Use SENTRY_AUTH_TOKEN, not the VITE_ alias: the app reads the whole import.meta.env object, so Vite copies every VITE_* variable into the public bundle. | sidedoc-frontend/vite.config.ts |
SENTRY_RELEASE | VITE_SENTRY_RELEASE, else the package version | Release name the source maps are uploaded under. | sidedoc-frontend/vite.config.ts |
Backup places (@sidedoc/backend)
Which backup places the Settings window of the standalone editor can connect to (see the Persistence page of the deployment guide). Read by createPersistenceUiController in @sidedoc/backend from import.meta.env, so only the VITE_* names take effect in a SideDoc build. Build-time only: config.js (run-time configuration) does not cover them.
Example file: app/sidedoc-frontend/.env.example.
| Variable | Default | Description | Read in |
|---|---|---|---|
VITE_ENABLE_LOCAL_FS_PERSISTENCE | true | Offer backups to a local folder (File System Access API, Chromium-based browsers only). | sidedoc-backend/src/lib/application/services/persistence/local-fs-persistence-env.ts |
VITE_ENABLE_GOOGLE_DRIVE_PERSISTENCESIDEDOC_ENABLE_GOOGLE_DRIVE_PERSISTENCE (alias) | false | Offer backups to the user's Google Drive (app data folder). Needs VITE_GOOGLE_OAUTH_CLIENT_ID and a CSP that allows Google's sign-in and the Drive API, which the built-in policies do not. | sidedoc-backend/src/lib/application/services/persistence/google-drive-persistence-env.ts |
VITE_GOOGLE_OAUTH_CLIENT_IDSIDEDOC_GOOGLE_OAUTH_CLIENT_ID (alias) | empty | OAuth client id (type Web application) with the SideDoc origin as an authorised JavaScript origin. Not a secret. | sidedoc-backend/src/lib/application/services/persistence/google-drive-persistence-env.ts |
S3 storage (@sidedoc/backend)
S3-compatible storage offered in the Settings window of the standalone editor (bring your own bucket; see the Persistence page of the deployment guide). Read by createPersistenceUiController in @sidedoc/backend from the env object the frontend passes in, which is import.meta.env. Known limitation: Vite puts only VITE_* variables into import.meta.env, and these settings have no VITE_* alias, so at the moment they do not reach the app and S3 cannot be switched on in a SideDoc build. They are build-time only: config.js (run-time configuration) does not cover them.
Example file: app/sidedoc-backend/.env.example.
| Variable | Default | Description | Read in |
|---|---|---|---|
SIDEDOC_ENABLE_S3_PERSISTENCE | false | Offer backups to an S3-compatible bucket (AWS S3, R2, MinIO, Scaleway, OVHcloud, ...). Users enter endpoint, bucket and keys in the Settings window. There is no VITE_ alias, so the SideDoc frontend cannot enable this yet: Settings reports S3 as disabled. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_ENDPOINT | empty | Preconfigured S3 endpoint URL. Leave empty to let users enter their own. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_BUCKET | empty | Preconfigured bucket name. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_REGION | auto | Region used for request signing. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_ACCESS_KEY_ID | empty | Secret. Preconfigured access key. Anything configured at build time is readable by every visitor; prefer leaving it empty. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_SECRET_ACCESS_KEY | empty | Secret. Preconfigured secret key. Same warning as the access key. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_FORCE_PATH_STYLE | true | Path-style URLs (https://endpoint/bucket/key). false uses virtual-host style (https://bucket.endpoint/key). | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |
SIDEDOC_S3_PERSIST_CREDENTIALS | false | Keep the keys a user entered in sessionStorage (cleared when the tab closes) instead of memory only (cleared on reload). Never localStorage. The standalone editor keeps the secret in its passkey vault instead, where the browser supports it. | sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts |