Skip to content

Container User & Privilege Model

SentriKat's container runs the long-lived gunicorn process as a non-root user (sentrikat, the container's sentrikat UID (check with docker compose exec sentrikat id)). This page explains the lifecycle and what operators need to know about volume permissions.

Lifecycle

  1. Container starts as root. Required for update-ca-certificates and chown of runtime directories.
  2. Entrypoint installs custom CAs and validates secrets (SECRET_KEY, DB_PASSWORD in production mode).
  3. Privilege drop via gosu sentrikat: the entrypoint exec's gunicorn as the sentrikat user. From this point master and workers all run as the container's sentrikat UID (check with docker compose exec sentrikat id).
  4. Workers fork from master, inheriting the sentrikat UID.

The application workers therefore run without root privileges.

Bind-mount permissions

Any host path mounted into the container must be writable by the container's sentrikat UID (check with docker compose exec sentrikat id):

Mount target Purpose Required ownership
/var/log/sentrikat Log files 999:999, mode 750
/app/data Uploads, encryption key 999:999, mode 750
/data/... (with STORAGE_ROOT) Persistent data 999:999, mode 750
/app/custom-certs Custom CA certificates 0:0 read-only OK

Set ownership before starting the container:

sudo mkdir -p /opt/sentrikat/{logs,data,backups}
sudo chown -R 999:999 /opt/sentrikat/{logs,data,backups}
sudo chmod -R 750 /opt/sentrikat/{logs,data,backups}

Change ownership of these directories only. Do not run a recursive chown or chmod on the whole install directory: .env (secrets) and ssl/key.pem must stay readable by their owner only (mode 600).

Troubleshooting

Symptom: Permission denied writing logs

docker compose exec -T sentrikat ls -la /var/log/sentrikat/
# If files show `root:root`, the gosu privilege drop did not happen.

Recovery: chown in a shell, restart the container.

Symptom: container starts but exits immediately

docker compose logs sentrikat
# Look for "FATAL: SECRET_KEY must be set" or similar.
# Production mode requires SECRET_KEY and DB_PASSWORD changed
# from their default values.

Symptom: gosu: command not found

Indicates an image without gosu. This should not happen with the image shipped in the release bundle: download the bundle again from the Customer Portal, load it as described in Updating, and contact support@sentrikat.com if it persists.

See also