Step 1: Full backup on the source VPS Stop only the data container—not the entire stack—to minimize downtime. Then back up the three volumes using a temporary Alpine container:
# On the source VPS, in the folder where your docker-compose.yml file is located
mkdir -p ~/netbird-full-backup
# Stop only netbird-server for consistency
docker compose stop netbird-server
# Back up the 3 volumes as tar.gz files
docker run --rm \
-v netbird_netbird_data:/data \
-v ~/netbird-full-backup:/backup \
alpine tar czf /backup/vol_netbird_data.tar.gz -C /data .
docker run --rm \
-v netbird_netbird_proxy_certs:/data \
-v ~/netbird-full-backup:/backup \
alpine tar czf /backup/vol_proxy_certs.tar.gz -C /data .
docker run --rm \
-v netbird_netbird_traefik_letsencryp:/data \
-v ~/netbird-full-backup:/backup \
alpine tar czf /backup/vol_traefik_le.tar.gz -C /data .
# restart
docker compose start netbird-server
# Back up configuration files
cp docker-compose.yml *.env management.json turnserver.conf ~/netbird-full-backup/ 2>/dev/null || true
Step 2: Prepare the destination VPS Install Docker and Docker Compose on the new VPS, then place the configuration files:
# Create a working directory (with the same name as the original so that the volumes retain the same prefix)
mkdir -p /opt/netbird && cd /opt/netbird
cp ~/netbird-full-backup/docker-compose.yml .
cp ~/netbird-full-backup/*.env . 2>/dev/null || true
cp ~/netbird-full-backup/management.json . 2>/dev/null || true
cp ~/netbird-full-backup/turnserver.conf . 2>/dev/null || true
Step 3: Restore the volumes BEFORE starting This is the critical step that the documentation omits. Create the volumes and restore their contents before launching the containers:
cd /opt/netbird
# Create empty volumes
docker volume create netbird_netbird_data
docker volume create netbird_netbird_proxy_certs
docker volume create netbird_netbird_traefik_letsencryp
# Restore content on each volume
docker run --rm \
-v netbird_netbird_data:/data \
-v ~/netbird-full-backup:/backup \
alpine sh -c "cd /data && tar xzf /backup/vol_netbird_data.tar.gz"
docker run --rm \
-v netbird_netbird_proxy_certs:/data \
-v ~/netbird-full-backup:/backup \
alpine sh -c "cd /data && tar xzf /backup/vol_proxy_certs.tar.gz"
docker run --rm \
-v netbird_netbird_traefik_letsencryp:/data \
-v ~/netbird-full-backup:/backup \
alpine sh -c "cd /data && tar xzf /backup/vol_traefik_le.tar.gz"
# Lift the entire stack
docker compose up -d