Backups.
Make one, every night, restore.
Everything the studio stores lives in DATA_DIR. npm run backup packs it safely while the server runs, a cron line does it every night, and npm run restore brings it back into an empty folder.
01What is in DATA_DIR
Everything a studio stores is in DATA_DIR:
| In DATA_DIR | What it is | In a backup |
|---|---|---|
studio.sqlite | Accounts, workspaces, channels, episodes (research, scripts, fact checks, packages), storyboards, renders, credits, payments, YouTube sign-ins (encrypted) | always |
admin.sqlite | Console: settings, encrypted keys, team, audit log | always |
.admin-secret-key | The generated secret key (only when ADMIN_SECRET_KEY is not in .env) | when it exists |
files/assets | Every workspace's uploads and downloaded footage clips with their credits | always |
files/episodes | Episode thumbnails (the chosen one and the alternatives) | always |
files/music | The music library | always |
files/renders, files/voicecache | Rendered videos and cached voiceovers | only with --with-renders |
Rendered videos can be rendered again and are usually the largest part, so they are left out unless you ask.
02Make a backup
On Windows: the server is meant to run on Linux. On a Windows PC, run the commands on this page inside WSL 2 with Ubuntu (in PowerShell: wsl --install -d Ubuntu), or use Docker Desktop with its WSL 2 backend.
In the studio's folder:
npm run backup
It writes channelsmith-backup-YYYYMMDD-HHMMSS.tar.gz into DATA_DIR/backups (or into BACKUP_DIR when that is set in .env). It is safe while the server runs: the databases are copied with SQLite's online backup, checked with SQLite's integrity check, and only then packed. The archive is readable by its owner only.
Options (after --):
| Option | Effect |
|---|---|
--out /mnt/backups | Write somewhere else this time |
--keep 14 | Afterwards delete all but the newest 14 backups in that folder |
--with-renders | Include rendered videos and cached voiceovers |
With Docker: docker exec channelsmith npm run backup. The backup lands in the data volume under /app/data/backups.
The console's System health page shows when the last backup was made and where it is.
03Every night
crontab -e as the user that runs the studio, and add (change the folder to yours):
0 3 * * * cd /opt/channelsmith && /usr/bin/npm run backup -- --keep 14 >> backup.log 2>&1
With Docker, in the host's crontab:
0 3 * * * docker exec channelsmith npm run backup -- --keep 14 >> /var/log/channelsmith-backup.log 2>&1
Copy backups off the server. A backup on the same disk is lost with the disk. For example, from another machine: rsync -a server:/opt/channelsmith/data/backups/ ~/studio-backups/. A backup contains your customers' data and, when the key was generated, the key that opens the saved API keys: store it like a password.
If ADMIN_SECRET_KEY is in .env, the backup does not contain it. Keep a copy of .env (or at least that line) with your backups.
04Restore
A restore goes into an empty DATA_DIR only, so it can never mix two installs.
- Stop the server (
sudo systemctl stop channelsmithordocker stop channelsmith). - Move the old data away:
mv data data-old(abackupsfolder alone inDATA_DIRis allowed to stay). Restore:
npm run restore data-old/backups/channelsmith-backup-20261109-030000.tar.gz- Start the server again.
The restore checks the archive and both databases before it moves anything into DATA_DIR, and warns when:
- the backup was made with a newer Channelsmith than the one installed (install that version first);
ADMIN_SECRET_KEYin.envis not the key the backup was made with (put the old key back, or enter the API keys again).
With Docker, restore into a new volume from a stopped container:
docker volume create channelsmith-data-restored
docker run --rm --env-file .env -v channelsmith-data-restored:/app/data -v "$PWD/backups:/restore:ro" \
channelsmith npm run restore /restore/channelsmith-backup-20261109-030000.tar.gz
Then start the container with -v channelsmith-data-restored:/app/data.