Docker¶
Image¶
giiibates/justup on Docker Hub,
multi-arch for linux/amd64 and linux/arm64.
Docker Compose¶
docker/docker-compose.yml pulls the published image. Excerpt:
services:
justup:
image: ${JUSTUP_IMAGE:-giiibates/justup:latest}
container_name: justup
init: true
restart: unless-stopped
stop_grace_period: 60s
environment:
PUID: 1000
PGID: 1000
LOG_LEVEL: INFO
SECRET_KEY: ${SECRET_KEY:?Set a persistent key for justUp}
SECRET_KEYS: ${SECRET_KEYS:-}
volumes:
- ./:/app/data
tmpfs:
- /app/data/pdf_reports:size=256m,mode=0700,uid=1000,gid=1000
The file also sets log rotation (50 MB x 5), a health check on /healthz, and
the hardening options below.
./is relative to the Compose file, so data lands in the repository'sdocker/directory. Change the mount for another location. Starting the same stack from another directory (a copied Compose file, a re-imported stack) mounts an empty data directory: the database, users and sessions seem gone.- Compose reads
.envfrom the directory of the Compose file (docker/), not from the directory you run the command in. Use--env-fileto be explicit. - PDF reports live in a 256 MiB
tmpfsand are gone after a restart. - The file publishes no port. Add
ports: ["8000:8000"]underservices.justupor connect the service to a reverse proxy.
SECRET_KEY is required
The start aborts without it. Keep the key stable; otherwise stored secrets cannot be decrypted and all sessions end, because the session-token hashes are keyed with it. Mount the data volume persistently as well.
Behind a reverse proxy, set UPMON_TRUSTED_PROXIES
Add UPMON_TRUSTED_PROXIES with the proxy address as the container sees it.
Without it, the login rate limit and audit log record the proxy IP for every
client. See Reverse proxy.
Shutdown¶
docker stop triggers an orderly shutdown (schedulers, PDF worker, Signal,
database). stop_grace_period: 60s keeps Docker from killing the container
after 10 s. After a hard kill, SQLite recovers its WAL on the next start.
Ping and traceroute¶
ping and mtr need cap_net_raw. The image sets it on the binaries, and the
Compose file adds NET_RAW back to the capability set.
Container hardening¶
- The entrypoint starts as root only to set up
PUID/PGIDand the data directory, then drops privileges withgosu. - Missing data subdirectories are created as the service user. A recursive
chownruns only when the owner of/app/datadiffers fromPUID:PGID. - The Compose file drops all capabilities and adds back
CHOWN,FOWNER,SETUID,SETGID, andNET_RAW.no-new-privilegesis set. /healthzis public and checks liveness only. It returnsokand a timestamp and, when the service supervisor is available,degradedand the state of each background service. Error details and crash counters are not exposed.
signal-cli¶
The image bundles Java 25 (Temurin) and signal-cli for Signal notifications.
Tune memory with JAVA_XMS and JAVA_XMX. See Notifications.
Logs¶
Uvicorn access lines appear only at LOG_LEVEL=DEBUG. The initial admin password
is printed to the container output, so restrict access to the Docker logs.