How to Fully Restore Docker Volumes From Backup on Ubuntu (Complete Guide With rsync, Permission Fixes & Safety Checks)

How to Fully Restore Docker Volumes From Backup on Ubuntu (Complete Guide With rsync, Permission Fixes & Safety Checks)

Restoring a Docker server after system migration, disk failure, or a panel crash (such as Webuzo or a VPS reinstatement) requires careful handling — especially when your applications depend on persistent data stored in Docker volumes.

In this guide, we walk through the exact steps used to restore multiple Docker volumes (Vaultwarden, Odoo, Keycloak, Chatwoot, and more) from a backup directory such as:

/mnt/backup/docker-backup/var/lib/docker/volumes/

This article is based on a real-world server recovery scenario involving dozens of volumes and containers.


✔️ Prerequisites

You must have:

  • Docker installed on the target machine
  • Root access to the system
  • Enough disk space

A backup directory containing your Docker volumes
Example structure:

/mnt/backup/docker-backup/var/lib/docker/volumes/<volume_name>/_data

1. Verify the Backup Directory Structure

Before restoring, ensure your backup actually contains the Docker volumes:

ls /mnt/backup/docker-backup/var/lib/docker/volumes/

Typical output:

devops_lipanet_chatwoot_data
nestict_vaultwarden_data
nestict_keycloak_data
nestict_ghost_content
nestict_odoo-db_odoo-db-data
...

If you see folders ending with _data, you’re good.


2. Stop Docker (VERY Important)

To avoid database corruption (especially for PostgreSQL, SQLite, MariaDB, Redis):

systemctl stop docker

This freezes all containers and releases volume locks.


3. Restore ALL Docker Volumes Using rsync

To restore volumes from backup to the live Docker storage:

rsync -avh --progress \
/mnt/backup/docker-backup/var/lib/docker/volumes/ \
/var/lib/docker/volumes/

What this does:

  • -a → archive mode (preserves permissions, owners, links)
  • -v → verbose
  • -h → human-readable
  • --progress → show file transfer progress
  • Trailing / → ensures correct directory merging

Typical rsync output:

sending incremental file list
./
metadata.db
4812738e2ea9c598847bc06f322e1879.../_data/jvb.conf
...
sent 271.62K bytes  received 235 bytes

You might notice very low transferred data size — this is normal.
Rsync only copies changed files.


4. Fix Permissions for Sensitive Containers

Docker containers rely on specific UIDs/GIDs to access their volumes.

Vaultwarden (Rust / UID 1000)

chown -R 1000:1000 /var/lib/docker/volumes/nestict_vaultwarden_data/_data

Odoo (UID 1000)

chown -R 1000:1000 /var/lib/docker/volumes/*odoo*/* 2>/dev/null || true

PostgreSQL (Keycloak, Chatwoot, Odoo DB) – UID 999

chown -R 999:999 /var/lib/docker/volumes/*postgres*/* 2>/dev/null || true

Chatwoot

No special permissions required unless logs show errors.


5. Start Docker Again

systemctl start docker

Check running containers:

docker ps

6. Restart All Containers

Method 1 — Restart all running containers:

docker restart $(docker ps -q)

Method 2 — If using docker-compose:

cd /path/to/compose/project
docker compose restart

For example (Zammad installation):

cd /home/nestict/git/zammad-docker-compose
docker compose restart

7. Validate Each Service After Restore

Check logs for errors:

Vaultwarden

docker logs vaultwarden

Keycloak

docker logs <keycloak-container-name>

Odoo

docker logs <odoo-web-container>

Chatwoot

docker logs devops_lipanet_chatwoot_app

If any container fails to start, logs will show missing permissions, DB migration issues, or wrong file paths.


8. Common Issues and Fixes

❌ “permission denied” errors after restore

→ Wrong UID on volume.

Fix using chown -R <uid>:<gid>.

❌ Vaultwarden won’t start (SQLite locked)

Delete WAL file:

rm /var/lib/docker/volumes/nestict_vaultwarden_data/_data/db.sqlite3-wal

❌ Keycloak fails due to Postgres permissions

Run:

chown -R 999:999 /var/lib/docker/volumes/*postgres*/_data

9. Best Practices for Docker Backup & Restore

✔️ Always stop docker before restoring volumes

✔️ Never restore volumes while containers are running

✔️ Use rsync instead of cp for data consistency

✔️ Verify permission ownership per service

✔️ Test services individually after restore

✔️ Keep offsite backups (S3, Backblaze, rsync.net)

✔️ Use docker volume ls to confirm restored volumes


Conclusion

Restoring Docker volumes safely is critical when handling production systems hosting multiple services like Vaultwarden, Odoo, Keycloak, Zammad, Nextcloud, or Chatwoot. Using rsync ensures accurate, atomic file transfer while preserving structure and permissions.

With the method shown in this guide, you can recover an entire multi-container environment quickly and reliably.

Read more