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.productionand/home/xtreamgo/CREDENTIALS.txt.
What a backup contains
| Item | backup.sh | Backup made in the panel |
|---|---|---|
| Panel database (users, lines, streams, settings, resellers and all other tables) | Yes | Yes |
| Stored routines and triggers | Yes | Yes |
| Database events | No | Yes |
CREATE DATABASE and USE statements | Yes (dump made with --databases) | No |
/home/xtreamgo/.env.production and CREDENTIALS.txt | No | No |
Certificate files in /home/xtreamgo/ssl and nginx/conf.d/ssl.conf | No | No |
Media files, logos, HLS segments and recordings in the Docker volume xtreamgo_api_data | No | No |
| Anything on load balancer servers | No | No |
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
xtreamgo backupThis runs /home/xtreamgo/scripts/backup.sh. The script:
- Reads
DB_USER,DB_PASSandDB_NAMEfrom/home/xtreamgo/.env.production. - Checks that the container
xtreamgo-dbruns. - Runs
mariadb-dump --single-transaction --routines --triggers --databases xtreamgoinside the container and compresses the output. - Writes
/home/xtreamgo/backups/xtreamgo_<date>_<time>.sql.gz. - 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. - Deletes files named
xtreamgo_*.sql.gzin that directory that are older than 7 days. - Appends its messages to
/home/xtreamgo/backups/backup.log.
2. Check the result every time
echo "exit code: $?"
ls -lh /home/xtreamgo/backups/ | tail -3
tail -3 /home/xtreamgo/backups/backup.logA 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:
0 3 * * * /home/xtreamgo/scripts/backup.sh >/dev/null 2>&1The 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
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.
| Function | What it does |
|---|---|
| Create | Asks 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. |
| Verify | Tests the file again with gzip -t. |
| Download | Sends the file to your browser as <name>.sql.gz. |
| Restore | Loads the backup into the live database. Before that the panel saves the current database as pre-restore-<timestamp>.sql.gz and lists it. |
| Delete | Removes the backup. |
| Automatic backup | Off 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 storage | Upload 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:
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 ofJWT_SECRET,CUSTOMER_JWT_SECRETandPORTAL_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
docker stop xtreamgo-api
ROOTPW=$(grep '^DB_ROOT_PASSWORD=' /home/xtreamgo/.env.production | cut -d= -f2-)For a file made by backup.sh:
gunzip -c /root/xtreamgo_<date>_<time>.sql.gz | docker exec -i xtreamgo-db mariadb -uroot -p"$ROOTPW"For a file made in the panel:
gunzip -c /root/<name>.sql.gz | docker exec -i xtreamgo-db mariadb -uroot -p"$ROOTPW" xtreamgo5. 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
cd /home/xtreamgo
docker compose -f docker-compose.yml --env-file .env.production up -d --force-recreate apiUse 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:
docker inspect --format='{{.State.Health.Status}}' xtreamgo-api7. Correct the address of the main server
The restored database holds the IP address of the old server. Check and correct it:
xtreamgo dbSELECT 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>;
exitThe 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.txtdoes not apply, because the admin account now comes from the backup. - The License page can show
License state missing on initialized panelfor a short time. The message clears after the next successful license check, which runs every minute. - Run
ssl-setup.shagain 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
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 -1Expected 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:
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
| Message | Meaning | Action |
|---|---|---|
ERROR: /home/xtreamgo/.env.production not found | backup.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 running | The 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 disk | The entry exists but the file is gone. | The file was deleted from the volume. Use another backup. |
Status restore_failed | The 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 restore | Wrong root password. | Read DB_ROOT_PASSWORD from the .env.production of the server you are on. |