Skip to content

Troubleshooting ​

Container does not start ​

The entrypoint validates every setting before nginx starts. On a problem it prints one line on stderr, starting with sidedoc-entrypoint: ERROR:, and exits with code 64. Read it with docker logs <container> or kubectl logs <pod>. The messages below are listed with an example; the cause and fix apply to every setting that can produce them.

To test settings without starting the server, run only the entrypoint:

sh
docker run --rm --read-only --tmpfs /tmp --env-file sidedoc.env sidedoc:0.6.1 true

SIDEDOC_SENTRY_DSN and SIDEDOC_SENTRY_DSN_FILE are both set ​

Cause: A setting is given both directly and as a file.

Fix: Remove one of the two.

SIDEDOC_SENTRY_DSN_FILE: cannot read /run/secrets/sentry_dsn ​

Cause: The file does not exist in the container, or uid 101 cannot read it.

Fix: Check the secret mount and its mode. Docker secrets and Kubernetes secret volumes are readable by default; host bind mounts may need chmod 0444 or a matching group.

SIDEDOC_REAL_IP_FROM must be a single line ​

Cause: The value, or the file contents without trailing newlines, contains a newline.

Fix: Put lists on one line, separated by spaces.

SIDEDOC_LOG_LEVEL: invalid value 'warning' ​

Cause: The value does not match the allowed pattern of that setting. Common mistakes: double quotes or a ; in a CSP source list, a Sentry DSN with a non-hex key or a non-numeric project id, a log level spelled warning.

Fix: Compare the value with the Allowed column on the Configuration page.

SIDEDOC_SENTRY_ENABLED: expected true/false, got 'enabled' ​

Cause: A boolean setting has another value.

Fix: Use true/false (or 1/0, yes/no, on/off).

SIDEDOC_PORT must be 1024-65535 (unprivileged) ​

Cause: The container runs as a non-root user and cannot bind ports below 1024.

Fix: Keep the container port at 8080 (or another high port) and publish it on 80/443 through the host or the proxy: -p 80:8080.

SIDEDOC_SCHEMA_VERSION=0.3.0: no bundled schemas/0.3.0 (have: 0.1.1 0.1.2 0.2.1 0.2.2 ) ​

Cause: The image does not contain that schema version.

Fix: Pick one of the listed versions, or use an image that bundles the version (see Schemas).

SIDEDOC_SENTRY_ENABLED=true requires SIDEDOC_SENTRY_DSN ​

Cause: Sentry is enabled without a DSN.

Fix: Set SIDEDOC_SENTRY_DSN or SIDEDOC_SENTRY_DSN_FILE, or disable Sentry.

/tmp must be writable: mount a tmpfs (docker run --read-only --tmpfs /tmp, or an emptyDir) ​

Cause: The root filesystem is read-only and nothing writable is mounted at /tmp, or the mount is not writable for uid 101.

Fix: Add --tmpfs /tmp (Docker), tmpfs: [/tmp] (compose) or an emptyDir volume at /tmp (Kubernetes). With a tmpfs that sets uid=/mode=, make sure uid 101 can write.

generated nginx configuration is invalid ​

Cause: nginx -t rejected the rendered configuration. The lines before this message show nginx's own error. With validated settings this should not happen; a modified nginx.conf or an unusual CSP value are the likely causes.

Fix: Read the preceding nginx message. Report it as a bug if you run an unmodified image.

Container starts, but ​

The health check fails ​

/healthz is served on SIDEDOC_PORT (default 8080). The Docker HEALTHCHECK follows SIDEDOC_PORT; Kubernetes probes and load balancers must use the same port. A probe against the proxy in front, instead of the container, tests the proxy too.

The page is blank ​

Open the browser console.

  • Refused to load ... because it violates the following Content Security Policy directive: something in front of the container adds its own Content-Security-Policy header, or an extension injects scripts. Browsers enforce every policy they receive. Remove the extra header at the proxy.
  • 404 for config.js or assets/... when SideDoc runs under a sub-path: the proxy does not strip the prefix. See Serving under a sub-path.
  • 405 responses: only GET and HEAD are allowed. Some health checkers or proxies send OPTIONS or POST.

The access log shows the proxy's address, not the client's ​

Set SIDEDOC_REAL_IP_FROM to the address the container sees for the proxy, and make sure the proxy sends X-Forwarded-For. With Docker port publishing the address is often the bridge gateway (172.17.0.1), not 127.0.0.1.

Sentry receives nothing ​

  • Check that /config.js contains VITE_SENTRY_ENABLED: "true" and your DSN.
  • In the browser's network tab, look at POST monitoring/envelope. A 502 or 504 means the container cannot reach the Sentry host: it needs outbound HTTPS to the host in the DSN.
  • Ad blockers rarely block the same-origin tunnel, but privacy extensions can.

A frame or embed is refused ​

SIDEDOC_CSP_FRAME_ANCESTORS defaults to 'self'. Add the embedding site, with the single quotes on keywords: SIDEDOC_CSP_FRAME_ANCESTORS="'self' https://portal.example.org". An unquoted self is accepted but means a host called self.

SIDEDOC_CSP_FRAME_ANCESTORS from a Compose env file loses its quotes ​

Compose env_file and .env files strip one level of quotes. Write "'self'" there, or put the value under environment: in compose.yaml. docker run --env-file does not strip quotes.

Documents disappeared after moving the site ​

The workspace lives in the browser and belongs to the origin. A new domain, port or scheme starts with an empty workspace. Users can import their exported documents; see Persistence.

Old documents open read-only ​

Their datamodel version is below SIDEDOC_MIN_SUPPORTED_SCHEMA_VERSION. Users can convert them. See Schemas.

Static hosting ​

Headers are missing on /schemas/ or /vocab/ ​

nginx drops server-level add_header directives in any location that sets its own header, such as Access-Control-Allow-Origin. Include the headers again inside those locations, as in the nginx example.

A CSP added on the server has no effect ​

The default build also embeds a <meta> CSP, and the browser enforces both. Build with SIDEDOC_CSP_META=false when the server sends the policy.

npm run build fails about schemas ​

The backend prebuild step needs a schemas checkout in SIDEDOC_SCHEMAS_DIR. Use scripts/build-static.sh, which does not, or see Build with a schemas checkout.