Keep a copy of your site data at all times. With good backups, you can recover everything exactly as it was if something goes wrong, without panic.

What you can do

  • Back up the database with one click, optionally packaged together with uploaded files.
  • Backup files can be downloaded, deleted, and used for restore.
  • Backups can run automatically on a schedule, so you don't have to click manually every day.
  • Before a restore, the system automatically saves another copy as a fallback.

How to make a manual backup

  1. Log in to the admin panel and go to the "System settings → Backups" page.
  2. Click the one-click backup button. If you need to include uploaded files, check "Include uploaded files".
  3. When the backup finishes, a record appears in the list with the file name, type, size, SHA256, source, creator, and time.
  4. To download, click "Download". The file is served as an attachment, accessible only to logged-in administrators, and the action is written to the audit log.

Backup files are stored in data/backups/. This directory is outside the site root public/ and is created automatically on the first backup. File names include a timestamp and a random part, so the download URL cannot be guessed.

Database backups are compressed by default and saved as .sqlite.gz. You can turn off "Compress backup files" under "System settings → Backups"; when off, backups are saved as uncompressed .sqlite.

How to restore

  1. In the list, expand "Restore" and enter the site name or "confirm".
  2. The system first validates the selected file; if validation fails, the restore is refused.
  3. After validation passes, the system automatically creates a "pre-restore" backup.
  4. The data in the backup overwrites the current database, while the current database structure is preserved.
  5. After the restore completes, all login sessions are cleared and every administrator must log in again.

A restore overwrites current data. Perform it during off-peak hours and make sure you have selected the correct backup.

How to set up scheduled backups

Configure these under "System settings → Backups":

SettingDefaultDescription
Automatic backup intervalDailyOptions: off, daily, weekly (weekly runs on Monday)
Run time03:15Runs in the site time zone, format HH:MM
Maximum backups to keep15When exceeded, the oldest scheduled backups are deleted automatically; manual backups and "pre-restore" backups are not deleted automatically
Compress backup filesOnDatabase backups are saved as .sqlite.gz; when off, they are saved as uncompressed .sqlite
Automatic database maintenanceWeeklyOptions: off, weekly; VACUUM runs only inside cron:run
Maintenance daySundayCalculated in the site time zone
Maintenance run time03:45Runs in the site time zone, format HH:MM
Optimize statistics after maintenanceOnRuns PRAGMA optimize after maintenance completes

Scheduled backups back up only the database and do not include uploaded files. The scheduler checks once per minute via cron:run whether a run is due, and runs only once per day (or per week).

Configure the scheduler

Replace /var/www/kingcms and the PHP path with the actual paths on your server. Running once per minute is recommended.

System crontab

* * * * * /usr/bin/php /var/www/kingcms/bin/kingcms cron:run >> /var/www/kingcms/data/cron.log 2>&1

Configure it as the user that runs the website (usually www-data) to avoid files being created with the wrong owner:

sudo -u www-data crontab -e

systemd service + timer

/etc/systemd/system/kingcms-cron.service:

[Unit]
Description=KingCMS scheduled tasks

[Service]
Type=oneshot
User=www-data
ExecStart=/usr/bin/php /var/www/kingcms/bin/kingcms cron:run

/etc/systemd/system/kingcms-cron.timer:

[Unit]
Description=Run KingCMS scheduled tasks every minute

[Timer]
OnCalendar=*:0/1
Persistent=true

[Install]
WantedBy=timers.target

Enable it:

sudo systemctl daemon-reload
sudo systemctl enable --now kingcms-cron.timer

BT Panel (BaoTa)

Under "Scheduled Tasks" (计划任务), create a new Shell script task, choose "N minutes" as the interval and enter 1, and use the same script content as the crontab command above. After saving, run it once manually to confirm there are no errors.

Shared hosting

Use the host's "Scheduled Tasks" or "Cron Jobs" feature to run the command above every minute. Hosts that cannot run Shell commands cannot use automatic backups and can only back up manually in the admin panel.

Windows Task Scheduler

Create a new task, set the trigger to "Daily" and check "Repeat task every 1 minute" with a duration of "Indefinitely"; set the action to "Start a program":

C:\php\php.exe C:\kingcms\x1\bin\kingcms cron:run

Set "Start in" to C:\kingcms.

Confirm it is running

The "System settings → Backups" page shows:

  • Last run: the time the scheduler last executed cron:run.
  • Last automatic backup: the creation time of the most recent scheduled backup.
  • Database file size / Reclaimable space / Last maintenance: database usage and maintenance results; click "Maintain now" to manually add a maintenance task to the queue.

If the scheduler has not run for more than 10 minutes, or has never run, a yellow warning bar appears at the top of the page.

Maintain the database

After data is deleted, the SQLite file does not shrink automatically. Weekly maintenance runs VACUUM, which rewrites the file as a compact copy; if "Optimize statistics after maintenance" is on, PRAGMA optimize also runs afterward.

  • Maintenance is executed only by the command-line scheduler cron:run; web requests never execute VACUUM directly.
  • If there has been no successful backup within 24 hours before maintenance, a scheduled backup is created automatically first; if the automatic backup fails, this maintenance run is skipped.
  • If the maintenance lock cannot be acquired or the database is busy, the run is skipped and logged, and retried in the next cycle.
  • Clicking "Maintain now" and confirming only adds a maintenance task to the queue; the scheduler executes it in the background.
  • Every maintenance run is written to the audit log with the action backup.vacuum.

Maintenance holds a database write lock, so schedule it during off-peak hours. Larger databases take longer to maintain.

Files to back up separately

app.key is not included in backups. It is used to decrypt key fields in settings. When moving to another server or reinstalling the system, back up data/app.key separately; otherwise the DeepSeek key, payment private key, API keys, and other secrets in the database cannot be decrypted.

Common issues

  • Last run never updates: first run php bin/kingcms cron:run manually on the command line to see the error; confirm the PHP path in crontab is correct and that the executing user has write permission on data/.
  • Command cannot find PHP: use which php or command -v php to find the absolute path, then put it in crontab.
  • Backup fails: check disk space and permissions on data/; the backup directory must be writable and creatable. If it reports that the sqlite3 extension is not enabled, install the PHP sqlite3 extension and restart PHP-FPM.
  • Run time is wrong: "Run time" is calculated in the site time zone. After changing the site time zone under "System settings → Settings → Site Basics → Basic Information", the next run will follow the new setting.
  • Packaging with media fails: the server needs the PHP zip extension enabled. If the upload directory does not exist, only the database is packaged.
  • Log location: if you redirect output to data/cron.log in crontab, check it there; you can also view execution logs under "Scheduled Tasks" in BT Panel; PHP-FPM or web server error logs record backup exceptions.

Related documentation: System Settings, Installation, Upgrade.