Persistent storage
Where Uptimer keeps data and config, and how to persist them.
Uptimer keeps state under one data directory and reads settings from one config file. Mount both from the host so they survive restarts.
Inside the image
/app/configs/default.yml # default (dev) config
/app/uptimer # the binary
/data/ # data_dir — database, keys, identities (mount this)
The data directory
general.data_dir (default /data, env UPTIMER__GENERAL__DATA_DIR) holds:
| File | What |
|---|---|
server.pem / server.uuid | Server identity — signs API keys, validates workers. |
worker.pem / worker.uuid | Worker identity. |
server_db.sqlite | Control-plane database (SQLite only). |
docker run -p 2517:2517 -v uptimer-data:/data ghcr.io/myuptime-info/uptimer:1.3.0
Lose server.pem and existing API keys and UI sessions stop validating; lose a worker’s
identity and it must be re-registered. Back up the volume — or use PostgreSQL plus a secret
store for the keys.
Custom config
Extract the default to edit it, then mount it back:
docker create --name tmp ghcr.io/myuptime-info/uptimer:1.3.0
docker cp tmp:/app/configs/default.yml ./uptimer.yml
docker rm tmp
docker run -p 2517:2517 \
-v "$PWD/uptimer.yml:/app/configs/config.yml" \
ghcr.io/myuptime-info/uptimer:1.3.0 --cfg /app/configs/config.yml server
--cfg is optional (defaults to configs/default.yml). Every key also has a UPTIMER__…
environment override — see Configuration.
Database
The DSN scheme picks the backend — sqlite3:// or postgres://. Server and worker can even
share one database; their tables use distinct prefixes.
SQLite — dev
Zero setup: a file under /data, created and migrated on boot.
server: { db: { dsn: sqlite3:///data/server_db.sqlite } }
worker: { db: { dsn: sqlite3:///data/worker_db.sqlite } }
PostgreSQL — production
Point the DSN at Postgres. Use two databases — uptimer_server (control plane) and
uptimer_worker:
server: { db: { dsn: "postgres://uptimer:secret@db:5432/uptimer_server?sslmode=disable" } }
worker: { db: { dsn: "postgres://uptimer:secret@db:5432/uptimer_worker?sslmode=disable" } }
Create both databases before first start (a Postgres init script is the easy way).
Migrations
- SQLite is auto-migrated on boot — convenient for dev, not guaranteed safe across upgrades.
- PostgreSQL uses versioned migrations (schema changes + data backfills). By default they
run at boot (
server.db.boot_migrate: true). For production, run them once with the dedicateduptimer migratejob and setboot_migrate: falseon the app containers — the schema is then brought to head atomically, once, instead of by each booting replica.
Background: Choosing a database.
Bootstrap identities
server init / worker init generate the keys and UUIDs (add --force to regenerate — note
that regenerating the server key invalidates existing sessions):
docker run -v uptimer-data:/data ghcr.io/myuptime-info/uptimer:1.3.0 server init