← Back to library
Panel Practice

Backing up and updating the panel without downtime

A service most often dies quietly: a node went down overnight, a cert expired, the database wasn't backed up — and you find out from the stream of negativity. Below — how to close this off in advance: database backup, auto-export off-server, a tested restore, and monitoring with alerts. Enter your own data in the builder above.

This material covers the engineering of your own network infrastructure and is educational in nature. Complying with the laws of your own jurisdiction is on you.

Why this isn't optional

No database backup = a hijack, failure, or seizure of the server = loss of all clients. In the Remnawave database is everything: users, terms, nodes, squads. Restoring it by hand is impossible. So a backup isn't "I'll set it up someday" but the first thing you do once clients appear.

The second silent killer is the absence of monitoring. A node went down at three in the morning, clients are without internet, and you're asleep and find out in the morning from a flood of complaints. Let's break down both fronts.

Dumping the database in one command

PostgreSQL in the panel's container is dumped in one command. At the same time we pack up the configs:

bash
cd /opt/remnawave
docker compose exec -T remnawave-db pg_dump -U postgres postgres > backup-$(date +%F).sql
tar czf conf-$(date +%F).tgz .env docker-compose.yml

This is done before any experiments with the panel — before editing inbounds, before an update, before any "what if." The dump is taken on a live panel without stopping it — clients notice nothing.

Auto-backup on cron with off-server export

You'll forget to back up by hand within a week. Set up a daily dump on cron and export off the server (a backup on the same server that got seized is useless):

bash
cat >/etc/cron.d/rw-backup <<'EOF'
0 4 * * * root cd /opt/remnawave && docker compose exec -T remnawave-db pg_dump -U postgres postgres | gzip > /root/backups/db-$(date +\%F).sql.gz
EOF

Then export to the cloud (set up rclone in advance to a different provider):

bash
# after the cron dump — copy off-server
rclone copy /root/backups remote:vpn-backups

Storage rules:

  • In a different place — a different provider/cloud, not the same server.
  • 7–14 copies — so you can roll back not to "yesterday" but to any of the recent days (if you didn't spot the breakage right away).

A restore you've actually tested

A backup that doesn't restore isn't a backup. The restore order: bring up only the database, pour in the dump, bring up the panel:

bash
cd /opt/remnawave
docker compose up -d remnawave-db                 # bring up only the DB
gunzip < /root/backups/db-2026-06-05.sql.gz | \
  docker compose exec -T remnawave-db psql -U postgres postgres   # pour in the dump
docker compose up -d                              # bring up the whole panel

After the restore, check: users, nodes, squads in place, nodes came up online. And most important — regularly test the restore on a spare server. "A backup nobody ever restored" has a way of not restoring at the moment you need it.

Updating without downtime

Updating the panel is a reload of the images. The correct order: took a backup, pulled the new images, recreated the stack:

bash
cd /opt/remnawave
docker compose exec -T remnawave-db pg_dump -U postgres postgres > backup-before-update.sql
docker compose pull
docker compose up -d
docker compose logs -f

The downtime is seconds to recreate the containers. Clients already connected to nodes notice nothing at all: their traffic goes through the nodes, not the panel. During the restart the panel is unavailable only for new subscriptions and the admin UI.

Important about .env: if you changed environment variables, an ordinary restart won't re-read them — you need a full recreate (down + up). Updating images via pull + up recreates the containers, so the env gets picked up there.

Monitoring that wakes you before clients do

To avoid learning of an outage from complaints — a lightweight monitor with Telegram alerts. Uptime Kuma comes up in a couple of minutes:

bash
docker run -d --restart=always -p 127.0.0.1:3001:3001 \
  -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1

Put it behind a reverse proxy and add monitors:

  • TCP to nodes (IP:443) — catches a downed node.
  • HTTP to the subscription page — if it doesn't respond, clients are left without configs.
  • In Notifications → Telegram: bot token and chat_id → an outage lands in the bot.

Interval 60 seconds and 2–3 retries, so it doesn't nag on channel flicker.

What else to monitor

Beyond availability — the silent killers of margin and functionality:

  • Hosting balance — hit zero and the server gets shut down. Set up reminders at the provider.
  • Certificates — an expired cert takes everything down. certbot sets a timer itself; check it: systemctl list-timers | grep certbot.
  • Node disk and RAM — overflow crashes Xray.
  • Extra stopped VPSes — they tick on the bill, the main killer of margin. Delete them.

Backup is set up, restore is tested, monitoring wakes you before clients — the service has stopped dying quietly. Next in this section — panel admin (roles, access, password reset) and managing client limits. And why dead servers eat profit was covered in the economics from the "Basics" section.

Next guide Panel admin: roles, access, password reset → Article unclear or something off? Message me and I will help or fix it. @notrealvpn →
This material is educational and covers network-infrastructure engineering. You are responsible for complying with the laws of your jurisdiction.