Move your Hub to a new machine
When you change hardware, you can move a Hub — installed apps, app data, and settings — by copying two things to the new machine: its data folder, and the Docker volume that holds its database.
To back up a single app rather than the whole Hub, use Hub’s per-app backups: Backup now on the app’s Backups card, before an update, or through an agent on Hub MCP. See Backup & Restore.
Before you start
You need:
- Docker installed on the new machine — see Install Docker
- Companion Hub installed on the new machine, at the same version, started once and then stopped. This creates the correct folder structure, database volume, and system integration before you copy the data over.
- Enough free disk space on the new machine for the data you’re moving
- A Linux or macOS shell — the commands on this page assume one
Find your Hub data folder (ROOT_FOLDER_HOST) on the old machine. cihub doctor prints it on the Root folder line. The defaults are ~/.local/share/companion-hub on Linux, ~/Library/Application Support/companion-hub on macOS, and %APPDATA%\companion-hub on Windows. Folder structure explains what’s inside.
A Hub keeps its state in two places, and you need both:
- The data folder holds app data, installed app files, your per-app config, and Hub settings.
- The
ci_hub_pgdataDocker volume holds the Hub database: operator accounts, the list of installed apps, and API keys. It is not inside the data folder, so an archive of the data folder alone moves your files but starts the new Hub with an empty database.
flowchart LR
subgraph OLD["Old machine"]
IN["Data folder: app-data, apps, user-config,<br/>state, logs, cache"]
DB["Docker volume ci_hub_pgdata<br/>the Hub database"]
EX["Left behind on purpose: media, repos, backups,<br/>env file, docker-compose.prod.yml"]
end
IN -- "tar -czvf" --> AR["hub-data.tar.gz"]
DB -- "docker run alpine tar" --> AD["hub-db.tar.gz"]
AR -- "scp, rsync, external drive,<br/>or magic-wormhole" --> EXT
AD -- "scp, rsync, external drive,<br/>or magic-wormhole" --> EXT
subgraph NEW["New machine"]
EXT["Extract into the fresh install's<br/>data folder and database volume"] --> UP["cihub up --detached"]
end
EX -. "media: copy separately<br/>backups: copy to keep them" .-> EXT
NOT["Not in the archives: shared folders,<br/>mount points, firewall rules,<br/>CI Account pairing"] -. "re-apply by hand" .-> UPStop Hub on the old machine
cihub downConfirm nothing is still running before you archive — a live database will produce a corrupt copy:
docker psYou should see no ci-hub, ci-hub-db, ci-hub-queue, or traefik containers.
Archive the data folder
Run this from the parent of your data folder. Set DATA_ROOT to the path from cihub doctor first:
DATA_ROOT="$HOME/.local/share/companion-hub"
cd "$(dirname "$DATA_ROOT")"
NAME="$(basename "$DATA_ROOT")"
tar -czvf hub-data.tar.gz --anchored \
--exclude="$NAME/media" --exclude="$NAME/repos" --exclude="$NAME/backups" \
--exclude="$NAME/.env" --exclude="$NAME/.env.dev" --exclude="$NAME/docker-compose.prod.yml" \
"$NAME"The archive leaves out four things:
mediais large and usually better copied separately.reposholds legacy app-store clones that Hub doesn’t need.backupsholds your per-app backups. Drop that--excludeif you want them to come along.- The env file and
docker-compose.prod.ymlare specific to each machine: they hold absolute paths and the machine’s own secrets. Keep the new machine’s copies.
Keep --anchored and the $NAME/ prefix. Without them, tar also skips any folder named media or backups inside your apps’ data — for example app-data/<store>/<app>/media.
Archive the Hub database
Copy the database volume into an archive. This runs read-only against the volume:
docker run --rm -v ci_hub_pgdata:/source:ro -v "$PWD":/backup alpine \
tar -czf /backup/hub-db.tar.gz -C /source .Transfer the archives
Any file transfer works — scp, rsync, an external drive, or magic-wormhole for a one-off send between machines that can’t see each other. Move hub-data.tar.gz and hub-db.tar.gz.
Restore on the new machine
Stop the fresh Hub install, then extract the data folder over it. Run this as your own user, not as root, so the files keep the right owner:
cihub downtar -xzvf hub-data.tar.gz -C /path/to/parent/of/data/rootThen replace the fresh database with the old one. This deletes whatever is in the new ci_hub_pgdata volume:
docker run --rm -v ci_hub_pgdata:/target -v "$PWD":/backup alpine \
sh -c 'find /target -mindepth 1 -delete && tar -xzf /backup/hub-db.tar.gz -C /target'Start Hub and verify
cihub up --detachedcihub doctorOpen the dashboard and sign in with your account from the old machine. Your installed apps should be listed. Confirm a couple of them start.
After the move
- Re-apply host-specific configuration — shared folders, mount points, and firewall rules do not travel in the archive
- Check your network settings — the new machine has a different IP, so any manual DNS entries or port forwards need updating
- Pair the Hub again if you use remote access. Your CI Account registration belongs to the old machine’s device ID, and the tunnel token sits in a
tunnelfolder next to the data folder, which the archive doesn’t include. Ifcihub doctorshowsRegistrationasdegraded (portal_rejected), runcihub register --code <code>with a fresh pairing code. See Device Pairing. - Check the device ID — if you copied an env file with a
DEVICE_IDline,cihub doctorreportsDevice IDascopied from another machine, and Hub refuses to pair under it. Remove the line, or set it to the new machine’s own ID.
Don’t run both Hubs against the same CI Account registration at once. Stop the old machine for good, or reset its registration, before pairing the new one.