GUIDE, WITHOUT THE GUESSWORK

Dokploy server-to-server migration — volume-safe checklist for Hetzner moves

Dokploy migrations look like 'export the panel and import on the new server.' The volume question is what makes it actually risky. Here's the volume-safe migration checklist.

Dokploy server-to-server migration — volume-safe checklist for Hetzner moves

If you've spent any time in r/dokploy, the migration thread is familiar: "What's the best way to move my Dokploy install from one Hetzner server to another?" The replies always start with "export the panel and import on the new one," and then immediately someone asks: "what about the volumes?"

That second question is the real one. The panel export is easy. The volumes — the data that lives outside the panel's config — are where migrations get dangerous. A successful Dokploy migration is a successful volume migration. The panel is the small part of the work.

This checklist is the order of operations to get a Dokploy migration done without losing data.

What the panel export actually covers

Dokploy's export gives you:

What it does not cover:

The export covers the configuration. The migration has to also handle the state.

The migration order

Do these in order. Each step assumes the previous one is complete and verified.

1. Inventory everything

On the old server, list:

Write this inventory to a file in your repo. The migration is a checklist; the checklist is data.

2. Confirm backups exist and restore

Before you touch the migration, confirm:

If any of these fail, fix them before continuing. A migration without verified backups is a migration with no rollback.

3. Provision the new server

On the new Hetzner box:

Do not point any production DNS at the new server yet.

4. Import the panel export

Export from the old server via Dokploy's UI. Import to the new server. Verify:

The new panel now knows about the apps but they haven't been deployed yet.

5. Migrate the volumes

This is the load-bearing step. For each app that has volumes:

For databases

The safest move is to use the database's own backup/restore. Don't rsync a live Postgres data directory; you'll corrupt the destination.

For app volumes (uploads, caches, etc.)

Use rsync while the old service is still up:

# On the new server:
rsync -avz --delete root@old-server:/var/lib/docker/volumes/<volume>/_data/ /var/lib/docker/volumes/<volume>/_data/

Do this twice — once now, once during the cutover. The first pass moves most of the data; the second pass catches anything that changed during step 6.

6. Deploy the apps on the new server

With volumes in place, trigger a deploy of each app in Dokploy on the new server. The container starts; it sees the migrated volume; it should boot to the same state the old server was in.

Verify each app:

If any of these fail, do not proceed to DNS cutover. Diagnose first. The new server hasn't taken traffic yet.

7. The cutover

When the new server passes verification:

The cutover window is the only time both servers are simultaneously "in service." Keep it short.

8. Post-cutover verification

After cutover:

If nothing has gone wrong in 24 hours, you can begin decommissioning the old server.

9. Decommission the old server

When you're confident:

Don't skip the 30-day window. Migration issues often surface days or weeks later.

Common failure modes and how to avoid them

Postgres data directory copied while live. Symptom: new server's Postgres won't start, or starts with corruption. Fix: always use pg_dump/pg_restore or proper file system snapshots, never a live rsync of the data directory.

Environment variables missing on new server. Symptom: app starts but can't reach services. Fix: Dokploy's export sometimes loses env vars that were set outside the panel UI; cross-check from your local notes or the old container's docker inspect.

TLS certificate fails after cutover. Symptom: browsers show cert errors after DNS flip. Fix: Let's Encrypt has rate limits; if you bounced certs too many times, you might need to wait. Mitigate by lowering DNS TTL ahead of time so the flip is fast.

Stale DNS resolvers. Symptom: some users see the old server, some see the new. Fix: pre-lower TTL by 24 hours; expect a small window of mixed traffic.

Volume permissions mismatch. Symptom: app starts but can't write to its volume. Fix: check that the UID inside the container matches the UID on the host (docker exec and id vs ls -ln on the host path).

What this list deliberately doesn't cover

A few things people sometimes try to fold in:

The shorter you keep the change set during cutover, the easier the diagnosis when something does go wrong.

The summary

Dokploy migrations look like "export and import." The real risk is volumes — both the database data and the app files. The migration that succeeds: verified backups first, side-by-side new server with imported config, volumes migrated and verified before any DNS change, fast cutover, 24-hour rollback window, 30-day final backup. Each step protects the next one. Don't compress the order to save time; the time is in the rebuild if you skip a step.

From across the StoicSoft network

Hand-curated reads on the same topic from sister sites in the StoicSoft family.