Postgres on a Hetzner Volume
This guide moves the Kaja Postgres database from the server’s main disk to a separate Hetzner Volume. A Hetzner Volume survives server rebuilds: you can delete and recreate the server, reattach the volume, and your database is still there.
Replace anything in <angle brackets> with your own values.
1. Create the volume (Hetzner Console)
- Go to the Hetzner Cloud Console.
- Open your project, click Volumes → Create Volume.
- Pick the same location/region as your server.
- Set a size (leave room to grow: resizing later is easy, shrinking is not).
- Attach it to your Kaja server directly in this step (there’s an “Attach to Server” option).
- Choose Automatic mounting (filesystem ext4). Hetzner then formats the volume, mounts it at
/mnt/HC_Volume_<id>and adds the/etc/fstabentry for you. - Click Create & Buy now.
2. Check the mount on the server
SSH into your server:
ssh root@<your-server>
Confirm the volume is mounted and in fstab:
df -h | grep HC_Volume
grep HC_Volume /etc/fstab
Both should show /mnt/HC_Volume_<id>. Then create the folder Postgres will use. Make it a subfolder, because the volume’s root holds lost+found, and Postgres won’t create a new database in a data folder that isn’t empty:
mkdir /mnt/HC_Volume_<id>/pgdata
Use /mnt/HC_Volume_<id>/pgdata wherever this guide says /mnt/kaja-pgdata/pgdata, and skip to step 5.
If you chose Manual mounting instead (or the automatic mount didn’t happen), do steps 3–4 yourself. List disks to find the new volume:
lsblk
You’ll see a new device, usually something like /dev/sdb. Also get its stable ID (safer than /dev/sdb, which can change):
ls -l /dev/disk/by-id/ | grep scsi-0HC_Volume
Note this path, it looks like /dev/disk/by-id/scsi-0HC_Volume_12345678.
3. Format and mount the volume (manual only)
Format it (⚠️ this wipes the volume, so only do it once, on a fresh volume):
mkfs.ext4 /dev/disk/by-id/scsi-0HC_Volume_12345678
Create a mount point and mount it:
mkdir -p /mnt/kaja-pgdata
mount /dev/disk/by-id/scsi-0HC_Volume_12345678 /mnt/kaja-pgdata
mkdir /mnt/kaja-pgdata/pgdata
4. Make the mount permanent (manual only)
Without this step, the volume won’t be mounted after a reboot.
Open /etc/fstab:
nano /etc/fstab
Add this line at the end (use the by-id path from step 2):
/dev/disk/by-id/scsi-0HC_Volume_12345678 /mnt/kaja-pgdata ext4 defaults,nofail 0 2
Save, then test it works:
umount /mnt/kaja-pgdata
mount -a
If no error appears, it worked.
5. Find the current Postgres volume name
From your local machine (with the disco CLI installed):
disco volumes:list --project <postgres-addon-project-name>
This lists the volume name(s) Disco uses for Postgres. Note the exact name, called <volume-name> below.
6. Back up the current data
Still on your local machine:
disco volumes:export --project <postgres-addon-project-name> --volume <volume-name> --output pg-backup.tar.gz
This downloads a full backup of the current database volume. Keep this file safe until the whole process is confirmed working.
7. Stop Postgres
In the Disco dashboard (or CLI), stop/scale down the Postgres addon service so nothing writes to the database during the move.
8. Point the volume at the Hetzner disk
Back on the server, find and remove the old Docker volume, then recreate it as a bind mount to your new disk:
docker volume inspect <volume-name> # confirm it exists first
docker volume rm <volume-name>
docker volume create \
--driver local \
--opt type=none \
--opt o=bind \
--opt device=/mnt/kaja-pgdata/pgdata \
<volume-name>
This makes Docker’s volume named <volume-name> actually point at /mnt/kaja-pgdata/pgdata, which is your Hetzner Volume.
9. Restore the data
Back on your local machine:
disco volumes:import --project <postgres-addon-project-name> --volume <volume-name> --input pg-backup.tar.gz
This writes the backup into the newly relocated volume.
10. Restart Postgres
Start/scale the Postgres addon service back up in Disco.
11. Verify
- Check Postgres logs for errors.
- Connect to the database and confirm your data (tables, row counts) is intact.
-
Confirm the data really lives on the volume (
/mnt/HC_Volume_<id>if it was mounted automatically):df -h /mnt/kaja-pgdataIt should show real disk usage matching your database size.
Why this matters
If you ever rebuild or replace the server:
- Create a new server.
- Attach the same Hetzner Volume to it.
- Mount it. In the Console’s attach dialog pick Automatic (on an existing volume it only mounts, it doesn’t format), or repeat steps 3–4 by hand without the
mkfsline. The data is already there. - Reinstall Disco, set up the same volume-to-bind-mount step (step 8) before starting Postgres.
Your database data survives, because it never lived on the server’s main disk in the first place.
Next: