Guides

Backup and restore

The panel has two backup paths: the backup.sh script on the server and the Backups page in the panel. Both save the database. This document explains both, the restore on a fresh server and how to test a backup.

Before you start

  • Root access to the main server.
  • A second location for the backup files: another server, object storage or your own computer. A backup that stays on the same server does not protect against loss of that server.
  • A safe copy of /home/xtreamgo/.env.production and /home/xtreamgo/CREDENTIALS.txt.

What a backup contains

Itembackup.shBackup made in the panel
Panel database (users, lines, streams, settings, resellers and all other tables)YesYes
Stored routines and triggersYesYes
Database eventsNoYes
CREATE DATABASE and USE statementsYes (dump made with --databases)No
/home/xtreamgo/.env.production and CREDENTIALS.txtNoNo
Certificate files in /home/xtreamgo/ssl and nginx/conf.d/ssl.confNoNo
Media files, logos, HLS segments and recordings in the Docker volume xtreamgo_api_dataNoNo
Anything on load balancer serversNoNo

The installer and the panel do not back up the media volume. If you need these files, copy the Docker volume xtreamgo_api_data to another location yourself.

Backup with the script

1. Run it

bash
xtreamgo backup

This runs /home/xtreamgo/scripts/backup.sh. The script:

  1. Reads DB_USER, DB_PASS and DB_NAME from /home/xtreamgo/.env.production.
  2. Checks that the container xtreamgo-db runs.
  3. Runs mariadb-dump --single-transaction --routines --triggers --databases xtreamgo inside the container and compresses the output.
  4. Writes /home/xtreamgo/backups/xtreamgo_<date>_<time>.sql.gz.
  5. Checks the dump. When the dump command fails or reports an error, the script writes ERROR: database dump failed: <error text>, removes the incomplete file and ends with exit code 1.
  6. Deletes files named xtreamgo_*.sql.gz in that directory that are older than 7 days.
  7. Appends its messages to /home/xtreamgo/backups/backup.log.

2. Check the result every time

bash
echo "exit code: $?"
ls -lh /home/xtreamgo/backups/ | tail -3
tail -3 /home/xtreamgo/backups/backup.log

A good run prints Backup successful: <file> (<size>) and Backup complete. and returns exit code 0.

A failed run prints a line that starts with ERROR: and returns exit code 1. A failed database dump is reported as ERROR: database dump failed: followed by the error text of the dump command. No backup file is left behind in that case. The same line is written to backup.log.

Run the first command right after xtreamgo backup, so that it shows the exit code of the backup.

3. Schedule it

The installer does not schedule backup.sh. Add a line to the root crontab with crontab -e:

text
0 3 * * * /home/xtreamgo/scripts/backup.sh >/dev/null 2>&1

The script ends with a non-zero exit code on every failure, so a monitoring tool or a cron wrapper can act on it. The reason is in /home/xtreamgo/backups/backup.log.

Use exactly this path in the cron line: /home/xtreamgo/scripts/backup.sh.

4. Copy the file off the server

bash
scp /home/xtreamgo/backups/xtreamgo_<date>_<time>.sql.gz user@backup-host:/path/

Backup in the panel

Open Backups in the admin panel. Only administrators have access.

FunctionWhat it does
CreateAsks for a name. Runs mysqldump --single-transaction --routines --triggers --events in the database container and writes <name>_<timestamp>.sql.gz. The file is tested with gzip -t before the backup counts as complete.
VerifyTests the file again with gzip -t.
DownloadSends the file to your browser as <name>.sql.gz.
RestoreLoads the backup into the live database. Before that the panel saves the current database as pre-restore-<timestamp>.sql.gz and lists it.
DeleteRemoves the backup.
Automatic backupOff by default. When on, the default is every 24 hours at 03:00 with a retention of 30 days. A maximum number of backups can be set.
Cloud storageUpload to S3 compatible storage, FTP, Dropbox or Google Drive. A backup found on the remote storage can be fetched back into the local list.

The files are stored inside the Docker volume xtreamgo_api_data in the directory backups. On the host this is:

bash
ls -lh /var/lib/docker/volumes/xtreamgo_api_data/_data/backups/

The panel does not store its backups in the Docker volume xtreamgo_api_backups. Look for them in the directory above.

Restore on the same server

Use Restore on the Backups page. The status of the entry changes to restoring and then to restored or restore_failed. If the result is wrong, restore the entry of type pre-restore that the panel created just before.

Restore on a fresh server

1. Collect from the old server

  • The backup file (.sql.gz).
  • /home/xtreamgo/.env.production. You need the values of JWT_SECRET, CUSTOMER_JWT_SECRET and PORTAL_JWT_SECRET.
  • Your license key.

2. Move the license

The license is bound to the IP address of the old server. Move it first as described in License. Without this step the new panel reports License is bound to a different server IP and the admin panel stays locked.

3. Install the panel on the new server

Follow Install the main server. The installer creates an empty database and new secrets.

4. Stop the API and load the backup

bash
docker stop xtreamgo-api
ROOTPW=$(grep '^DB_ROOT_PASSWORD=' /home/xtreamgo/.env.production | cut -d= -f2-)

For a file made by backup.sh:

bash
gunzip -c /root/xtreamgo_<date>_<time>.sql.gz | docker exec -i xtreamgo-db mariadb -uroot -p"$ROOTPW"

For a file made in the panel:

bash
gunzip -c /root/<name>.sql.gz | docker exec -i xtreamgo-db mariadb -uroot -p"$ROOTPW" xtreamgo

5. Put the old secrets into the new configuration

Edit /home/xtreamgo/.env.production on the new server. Replace the values of JWT_SECRET, CUSTOMER_JWT_SECRET and PORTAL_JWT_SECRET with the values from the old server. The panel derives signing keys from these values, for example for login sessions and for Enigma2 setup links.

Do not copy DB_PASS, DB_ROOT_PASSWORD or SERVER_IP from the old file. The new database container was created with the new passwords.

6. Start the API with the new configuration

bash
cd /home/xtreamgo
docker compose -f docker-compose.yml --env-file .env.production up -d --force-recreate api

Use this command on a freshly installed server only. The API applies pending database changes at start. This can take several minutes. Wait until it is healthy:

bash
docker inspect --format='{{.State.Health.Status}}' xtreamgo-api

7. Correct the address of the main server

The restored database holds the IP address of the old server. Check and correct it:

bash
xtreamgo db
sql
SELECT id, server_name, server_ip, http_broadcast_port, is_main FROM streaming_servers;
UPDATE streaming_servers SET server_ip='<new-ip>', is_main=1 WHERE id=<id of the main server>;
exit

The installer uses the same statement with id=1 on a new installation.

8. Log in and finish

  • Log in with the admin password of the old panel. The password in the new CREDENTIALS.txt does not apply, because the admin account now comes from the backup.
  • The License page can show License state missing on initialized panel for a short time. The message clears after the next successful license check, which runs every minute.
  • Run ssl-setup.sh again for HTTPS. See HTTPS and domain.
  • Point your DNS records at the new server.
  • Reinstall the agent on each load balancer from the panel. The agent configuration holds the address of the old main server.
  • Media files from the old server are not part of the backup.

How to test a backup

Quick test

bash
F=/home/xtreamgo/backups/xtreamgo_<date>_<time>.sql.gz
gzip -t "$F" && echo "archive ok"
ls -lh "$F"
gunzip -c "$F" | grep -c '^CREATE TABLE'
gunzip -c "$F" | tail -1

Expected results: archive ok, a size that fits your database, a table count of several hundred, and a last line that starts with -- Dump completed on.

Full test

A full test loads the backup into a database and starts a panel on it. Do this on a spare server with the steps of "Restore on a fresh server" and a test license. Do not load a backup.sh file into your live database server to test it. The file contains USE xtreamgo and overwrites the live database.

How to check it worked

After a restore:

bash
xtreamgo health
curl -s http://127.0.0.1/api/v1/license/status
docker exec xtreamgo-db mariadb -uroot -p"$ROOTPW" xtreamgo -N -e "SELECT COUNT(*) FROM reg_users; SELECT COUNT(*) FROM streaming_servers;"

Expected results: all containers healthy, "licensed":true, and the user and server counts of the old panel. Then log in and test one subscriber line with a player.

If something goes wrong

MessageMeaningAction
ERROR: /home/xtreamgo/.env.production not foundbackup.sh cannot find the configuration.Run it as /home/xtreamgo/scripts/backup.sh or with xtreamgo backup.
ERROR: DB_PASS is not set in ...The configuration has no database password.Check .env.production.
ERROR: xtreamgo-db container is not runningThe database container is down.See item 4 of Troubleshooting.
ERROR: Backup file is empty!The dump produced no output. The empty file is removed.Check the database container and the free disk space.
ERROR: database dump failed: <error text>The dump command failed. The text after the colon is the message of mariadb-dump, for example an access error. The incomplete file was removed. Exit code 1.Act on the error text. For Access denied, compare DB_PASS in .env.production with CREDENTIALS.txt. Check free disk space.
The license is not valid, so a backup cannot be created. Open License to see the reason.The panel blocks new backups while the license is invalid.See License. Use xtreamgo backup in the meantime.
Backup file not found on diskThe entry exists but the file is gone.The file was deleted from the volume. Use another backup.
Status restore_failedThe load into the database failed. The note of the entry holds the reason.Restore the pre-restore entry. Check disk space.
ERROR 1045 (28000): Access denied during a manual restoreWrong root password.Read DB_ROOT_PASSWORD from the .env.production of the server you are on.

Back to documentation