Backups
Dump a self-hosted Doska's database and attachments with backup.sh, and restore them into an empty stack.
The backup script covers the bundled database and the local files volume. If you use S3 or a managed database, this guide doesn't apply.
Run backup.sh from your Doska directory any time:
./backup.sh
install.sh downloads it for you. If you set the stack up by hand, fetch it
first:
curl -O https://raw.githubusercontent.com/romenkova/doska/main/backup.sh
chmod +x backup.sh
It writes two files to ./backups/, both stamped with the same timestamp:
| File | What's in it |
|---|---|
doska-<stamp>.sql.gz | The bundled Postgres. |
doska-files-<stamp>.tar.gz | Card attachments, from the files volume. |
install.sh runs this for you before it redeploys over an existing database.
Restoring
Database
Restore the database into an empty one, with only db running. A booted
server has already migrated the schema and seeded the admin account, and the
dump would land on tables and rows that already exist:
docker compose -f docker-compose.selfhost.yml down --volumes
docker compose -f docker-compose.selfhost.yml up -d --wait db
gunzip -c backups/doska-XXXX.sql.gz | \
docker compose -f docker-compose.selfhost.yml exec -T db \
psql -v ON_ERROR_STOP=1 -U doska doska
Attachments
Put the attachments back into the recreated volume, before the server starts:
docker compose -f docker-compose.selfhost.yml up -d --no-start server
gunzip -c backups/doska-files-XXXX.tar.gz | \
docker run --rm -i -v <project>_doska-files:/data alpine tar xf - -C /data
docker compose -f docker-compose.selfhost.yml up -d
<project> is the compose project name, by default the lowercased name of the
directory you run from (with anything outside a-z0-9_- dropped, and any
leading - or _ stripped), or COMPOSE_PROJECT_NAME if you set one.
docker compose -f docker-compose.selfhost.yml config | head -1 prints the one in effect.
Restore both halves from the same timestamp. The database holds the rows that name the files, so a mismatched pair leaves cards pointing at blobs that aren't there.
What the script does
- Checks that
dockerand eitherdocker composeordocker-composeare available, and thatdocker-compose.selfhost.ymlsits in the current directory, otherwise you are not in your Doska directory and it stops. - Works out the compose project name (
COMPOSE_PROJECT_NAME, or the lowercased name of the directory, normalised the way compose normalises it), that is the prefix on the volumes. - Creates
./backups/and takes one timestamp, shared by both files. - Database. Skipped if
.envsetsDATABASE_URL(yours to back up through your provider), or if thedoska-pgdatavolume doesn't exist yet. Otherwise it starts thedbservice, waits up to 30s forpg_isready, and runspg_dumpinto a temp file before gzipping it tobackups/doska-<stamp>.sql.gz. Ifpg_dumpfails, nothing is written. - Attachments. Skipped if there is no
doska-filesvolume. Otherwise a throwawayalpinecontainer mounts the volume read-only and tars it tobackups/doska-files-<stamp>.tar.gz.