Skip to content

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=/path instead of NAME (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 ​

VariableDefaultAllowedDescriptionExample
SIDEDOC_PORT80801024 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_IPV6autoauto, true, falseAlso 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_FROMemptyspace-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 ​

VariableDefaultAllowedDescriptionExample
SIDEDOC_WORKER_PROCESSESautoauto or 1 to 99
pattern 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 ​

VariableDefaultAllowedDescriptionExample
SIDEDOC_LOG_LEVELwarndebug, info, notice, warn, error, critnginx error log level. The error log goes to stderr.info
SIDEDOC_ACCESS_LOGjsonjson, combined, offAccess 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 ​

VariableDefaultAllowedDescriptionExample
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_SRCemptyCSP 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_AGE00 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 ​

VariableDefaultAllowedDescriptionExample
SIDEDOC_SCHEMA_VERSIONbuild 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_VERSIONbuild 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) ​

VariableDefaultAllowedDescriptionExample
SIDEDOC_SENTRY_ENABLEDfalsetrue, falseBrowser 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_DSNemptyhttps://<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_ENVIRONMENTproduction1 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_RELEASEimage 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_RATE00 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.

VariableValueDescription
SIDEDOC_VERSIONvalue of the VERSION build argumentVersion 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.

ArgumentDefaultDescription
NODE_IMAGEnode:22.23.3-alpine3.24Base image of the build stage. Pin by digest for releases.
NGINX_IMAGEnginxinc/nginx-unprivileged:1.30.6-alpine3.24-slimBase image of the runtime stage. Pin by digest for releases.
VERSION0.0.0-devImage version: OCI label org.opencontainers.image.version and SIDEDOC_VERSION.
REVISIONunknownSource revision (git commit) for the OCI label org.opencontainers.image.revision.
CREATEDunknownBuild 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.

VariableDefaultDescription
SIDEDOC_IMAGEsidedoc:devImage to run (and the tag a --build produces).
SIDEDOC_VERSION0.0.0-devPassed 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.

VariableDefaultDescriptionRead in
SIDEDOC_SCHEMAS_DIRschemas/ next to the repository rootPath 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.mjs
sidedoc-backend/scripts/sync-dcat-mappings.mjs
sidedoc-frontend/scripts/sync-vocab.mjs
SIDEDOC_CSP_METAtrueEmbed 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 frontendSchemas 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.

VariableDefaultDescriptionContainer settingRead in
VITE_SCHEMA_VERSION0.2.2Datamodel version new documents use.SIDEDOC_SCHEMA_VERSIONsidedoc-frontend/src/config/schemaVersion.ts
VITE_MIN_SUPPORTED_SCHEMA_VERSION0.0.0Documents below this version open read-only.SIDEDOC_MIN_SUPPORTED_SCHEMA_VERSIONsidedoc-frontend/src/config/schemaVersion.ts
VITE_SENTRY_ENABLEDtrue in production builds, false in the dev serverBrowser error reporting. A production build from source reports errors unless this is false (or config.js sets it to "false").SIDEDOC_SENTRY_ENABLEDsidedoc-frontend/src/services/sentry.ts
VITE_SENTRY_DSNSideDoc's own Sentry projectSentry DSN. Set your own, or disable Sentry, when you host SideDoc yourself.SIDEDOC_SENTRY_DSNsidedoc-frontend/src/services/sentry.ts
VITE_SENTRY_TUNNEL/monitoring/envelopePath 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_ENVIRONMENTVite mode (standalone, app, ...)Sentry environment tag.SIDEDOC_SENTRY_ENVIRONMENTsidedoc-frontend/src/services/sentry.ts
VITE_SENTRY_RELEASEbuild timestampSentry release tag. Also the release name for source-map upload when SENTRY_RELEASE is not set.SIDEDOC_SENTRY_RELEASEsidedoc-frontend/src/services/sentry.ts
sidedoc-frontend/vite.config.ts
VITE_SENTRY_TRACES_SAMPLE_RATE0.1Fraction of page loads that send performance traces.SIDEDOC_SENTRY_TRACES_SAMPLE_RATEsidedoc-frontend/src/services/sentry.ts
VITE_SCHEMA_URLhttps://sidedoc.app/schemas/0.1.0/datasheet.jsonWorkspace app build (--mode app) only: datasheet schema to load.sidedoc-frontend/src/components/backend-demo/useWorkspaceLifecycleActions.ts
VITE_TYPE_LIBRARY_URLhttps://sidedoc.app/schemas/0.1.0/type-library.jsonWorkspace 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.

VariableDefaultDescriptionRead in
SENTRY_ORG
VITE_SENTRY_ORG (alias)
emptySentry organisation slug.sidedoc-frontend/vite.config.ts
SENTRY_PROJECT
VITE_SENTRY_PROJECT (alias)
emptySentry project slug.sidedoc-frontend/vite.config.ts
SENTRY_AUTH_TOKEN
VITE_SENTRY_AUTH_TOKEN (alias)
emptySecret. 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_RELEASEVITE_SENTRY_RELEASE, else the package versionRelease 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.

VariableDefaultDescriptionRead in
VITE_ENABLE_LOCAL_FS_PERSISTENCEtrueOffer 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_PERSISTENCE
SIDEDOC_ENABLE_GOOGLE_DRIVE_PERSISTENCE (alias)
falseOffer 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_ID
SIDEDOC_GOOGLE_OAUTH_CLIENT_ID (alias)
emptyOAuth 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.

VariableDefaultDescriptionRead in
SIDEDOC_ENABLE_S3_PERSISTENCEfalseOffer 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_ENDPOINTemptyPreconfigured S3 endpoint URL. Leave empty to let users enter their own.sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts
SIDEDOC_S3_BUCKETemptyPreconfigured bucket name.sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts
SIDEDOC_S3_REGIONautoRegion used for request signing.sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts
SIDEDOC_S3_ACCESS_KEY_IDemptySecret. 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_KEYemptySecret. Preconfigured secret key. Same warning as the access key.sidedoc-backend/src/lib/application/services/persistence/s3-persistence-env.ts
SIDEDOC_S3_FORCE_PATH_STYLEtruePath-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_CREDENTIALSfalseKeep 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