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¶
- Container starts as
root. Required forupdate-ca-certificatesandchownof runtime directories. - Entrypoint installs custom CAs and validates secrets (
SECRET_KEY,DB_PASSWORDin production mode). - Privilege drop via
gosu sentrikat: the entrypoint exec'sgunicornas thesentrikatuser. From this point master and workers all run as the container'ssentrikatUID (check withdocker compose exec sentrikat id). - Workers fork from master, inheriting the
sentrikatUID.
This model prevents two classes of bugs:
- A compromised gunicorn worker has no root privileges to escalate.
- The "master is root, workers are sentrikat" mismatch (silently breaking log file writes) cannot occur.
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 755 |
/app/data | Uploads, encryption key, backups | 999:999, mode 755 |
/data/... (with STORAGE_ROOT) | Persistent data | 999:999, mode 755 |
/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
sudo chmod -R 755 /opt/sentrikat
Troubleshooting¶
Symptom: Permission denied writing logs¶
docker exec 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 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 a base image without gosu. Should not happen with the official image — rebuild from a clean clone of the SentriKat repo.
See also¶
Dockerfile(look forRUN apt-get install ... gosu).docker-entrypoint.sh(look forexec gosu sentrikat "$@").- Logging & Observability