Backup & Restore
This guide covers backing up your Trackarr database and restoring it on a new server.
Why Backup?
Critical
It is strongly recommended to back up your PostgreSQL database to multiple locations. If a node fails, having backups in different locations (off-site storage, cloud providers, separate servers) ensures you can recover your data.
Backup Strategy
- Regular automated backups — Set up daily or hourly
pg_dumpbackups - Multiple destinations — Store copies on at least 2-3 different locations
- Test your restores — Periodically verify that backups can be restored successfully
- Encrypt backups — Always encrypt backups before storing them off-site
Creating a Database Backup
cd /opt/trackarr
docker compose exec postgres pg_dump -U tracker trackarr | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gzBacking Up Secrets
Don't forget your .env file
Your .env file contains critical secrets that cannot be regenerated. If you lose these, all existing passkeys and user sessions will be invalidated.
Always back up your .env file alongside your database:
cd /opt/trackarr
cp .env .env.backup_$(date +%Y%m%d_%H%M%S)Key secrets to preserve:
| Variable | Purpose |
|---|---|
IP_HASH_SECRET | Hashes peer IPs in the tracker — losing this breaks peer tracking continuity but doesn't compromise security |
NUXT_SESSION_SECRET | Seals sessions, and is the last fallback of both keys below. Unless you set them, losing it logs everyone out and loses every password verifier and TOTP secret, every notification channel's credentials and the instance's federation key |
CREDENTIAL_ENCRYPTION_KEY | Encrypts users.auth_verifier and users.totp_secret at rest. Falls back to CHANNEL_ENCRYPTION_KEY, then to the session secret. Lost, every member must reset their password and re-enrol TOTP — the API refuses to start on a changed key rather than tell everyone "Invalid credentials" |
CHANNEL_ENCRYPTION_KEY | Encrypts the notification-channel configs and the federation private key. Optional; falls back to the session secret. When set, this is the variable that must survive the move (not the session secret). |
Store a copy of your .env file in a secure location (password manager, encrypted storage) separate from your database backups.
Beyond the database
pg_dump holds the rows and nothing else:
- Uploaded files. The site logo, the favicon and uploaded fonts live in the
uploads_datavolume — or in the bucket, withSTORAGE_DRIVER=s3. Back that up too, or the restored site comes back without them. - Redis holds the live swarm, the stats accumulator and the caches. Losing it costs at most a minute of credit and one announce interval for the swarm to rebuild; it is not worth restoring across a move.
- Backups taken before a Panic hold, in clear, everything the panic encrypted afterwards. Keep that in mind when deciding how long they live and where.
Restoring a Backup
To restore your database on a new VPS:
1. Install Trackarr on the new server
Follow Getting Started to install Docker, clone the repo, configure .env, and start the production stack.
2. Stop the application
cd /opt/trackarr
docker compose -f docker-compose.prod.yml down3. Transfer your backup file to the new server
# From your old server or local machine
scp backup_20260102_120000.sql.gz user@new-server:/opt/trackarr/4. Start only the database container
cd /opt/trackarr
docker compose -f docker-compose.prod.yml up -d postgres5. Restore the backup
# Drop and recreate the database
docker compose -f docker-compose.prod.yml exec postgres dropdb -U tracker trackarr
docker compose -f docker-compose.prod.yml exec postgres createdb -U tracker trackarr
# Restore from backup
gunzip -c backup_20260102_120000.sql.gz | \
docker compose -f docker-compose.prod.yml exec -T postgres psql -U tracker trackarr6. Start all services
docker compose -f docker-compose.prod.yml up -dTIP
Make sure to update your .env file on the new server with the same secrets (IP_HASH_SECRET, NUXT_SESSION_SECRET, CHANNEL_ENCRYPTION_KEY if set) from your old installation. Without them the existing session cookies invalidate at the next login and every encrypted notification-channel config becomes unreadable.
Changing Domains
If you're migrating to a new domain (e.g., old-tracker.com → new-tracker.com):
1. Update DNS records
Create A records for your new domain pointing to your server's IP:
| Subdomain | Record Type | Value |
|---|---|---|
new-domain.com | A | Your VPS IP |
tracker.new-domain.com | A | Your VPS IP |
2. Update environment variables
Edit your .env file:
cd /opt/trackarr
nano .envUpdate these values:
DOMAIN=new-domain.com
TRACKER_DOMAIN=tracker.new-domain.com
NUXT_PUBLIC_TRACKER_HTTP_URL=https://tracker.new-domain.com/announce
NUXT_PUBLIC_TRACKER_UDP_URL=udp://tracker.new-domain.com:6969/announceSite title / tagline aren't env-driven
The display name and tagline are stored in the settings table and edited from /admin/branding. They follow the database when you restore — no need to set them in .env.
3. Regenerate SSL certificates
Delete the old Caddy data to force new certificate generation:
docker compose -f docker-compose.prod.yml down
docker volume rm caddy_data || true
docker compose -f docker-compose.prod.yml up -dCaddy will automatically obtain new Let's Encrypt certificates for your new domains.
WARNING
Changing the announce URL will invalidate all existing .torrent files and magnet links. Users will need to re-download torrent files with the new announce URL.