You're reading the docs for v1.4.0, which isn't released yet. Commands here pull :edge, the newest pre-release build. Go to the current release (v1.3.0) →
Operating › Persistent storage

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:

FileWhat
server.pem / server.uuidServer identity — signs API keys, validates workers.
worker.pem / worker.uuidWorker identity.
server_db.sqliteControl-plane database (SQLite only).
docker run -p 2517:2517 -v uptimer-data:/data ghcr.io/myuptime-info/uptimer:edge

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:edge
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:edge --cfg /app/configs/config.yml server

--cfg is optional (defaults to configs/default.yml). Every key also has a UPTIMER__… environment override — see Configuration.

Unlike dev, the server command needs a server identity on the /data volume first — if it exits with a missing server.uuid, run server init once against the same volume before starting it.

Database

Only the server has a database. The DSN scheme picks the backend — sqlite3:// or postgres://.

SQLite — dev

Zero setup: a file under /data, created and migrated on boot.

server: { db: { dsn: sqlite3:///data/server_db.sqlite } }

PostgreSQL — production

Point the DSN at Postgres. One database is enough:

server: { db: { dsn: "postgres://uptimer:secret@db:5432/uptimer_server?sslmode=disable" } }

Create it before first start (a Postgres init script is the easy way).

Changed in 1.4.0 — workers no longer have a database. A worker keeps its rules in memory and receives them over gRPC, so worker.db.dsn and UPTIMER__WORKER__DB__DSN are no longer read. Both are still accepted and ignored, so an existing configuration keeps working untouched — but you can now delete the setting, and drop the second uptimer_worker database once no 1.3.x worker is left running against it.

A worker still needs its /data volume: worker.uuid and worker.pem are its identity, and losing them means re-registering it in the dashboard.

Migrations

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:edge server init