Skip to Content
DocumentationCompanion HubDocker and Companion Hub

Docker and Companion Hub

Companion Hub is a management layer on top of Docker. Understanding a few Docker concepts helps you troubleshoot issues, back up data, and know what happens when you install or remove apps.

Core concepts

Image

An image is a read-only template โ€” a snapshot of an application and its dependencies. When you install Nextcloud from the App Store, Hub pulls the nextcloud:latest image from a registry (usually Docker Hub or GHCR). Images are cached on disk and can be reused by many containers.

Container

A container is a running instance of an image. Each app you install gets one or more containers. When you click Stop on an app card, Hub stops its container(s) but keeps the image and your data.

Volume

A volume (or bind mount) is persistent storage attached to a container. App databases, uploads, and configuration live here โ€” typically under your Hub data directory (ROOT_FOLDER_HOST), and some apps use Docker-managed named volumes instead. Stopping or removing a container does not delete volumes unless you explicitly choose to remove them.

Compose

Docker Compose defines how multiple containers work together (networks, ports, dependencies). Each App Store entry ships a docker-compose.json (or legacy .yml) that Hub renders into a compose project per app.

How the pieces relate

One image can back many containers, and each container keeps its data in volumes that outlive it โ€” stopping or removing a container leaves both the image and the volume in place:

The four terms at a glance

TermWhat it isWhere it livesWhen it goes away
ImageRead-only template of an app and its dependencies; reused by many containersImage cache on disk, pulled from Docker Hub or GHCROnly when you prune: docker image prune, or docker system prune -a for all unused images
ContainerA running instance of an image; one or more per installed appManaged by Hub as a compose project per appStop stops it but keeps the image and your data; uninstall stops it too
VolumePersistent storage: databases, uploads, configurationTypically under your Hub data directory (ROOT_FOLDER_HOST)Only if you explicitly choose to remove it
ComposeDefines how containers work together: networks, ports, dependenciesdocker-compose.json (or legacy .yml) shipped with each App Store entry
Each row summarises the definition above it; nothing here happens without an action you take.

What Hub manages for you

When you install an app, Hub:

  1. Pulls the required Docker images
  2. Generates an app.env file from your form inputs and Hub settings
  3. Publishes the appโ€™s port for local access and, when you expose the app publicly, adds Traefik routing for its public address. The appโ€™s page lists each address โ€” see Finding your appโ€™s URL
  4. Starts the compose stack and tracks status via Server-Sent Events

When you uninstall, Hub removes the appโ€™s containers, images, and installed files, and the dialog shows one switch, Delete all data, which is on by default. With it on, Hub also deletes the appโ€™s data folder, Docker volumes, and backups. With it off, all three stay, and the dialog says This appโ€™s data and backups stay on this Hub.

Inspecting Docker state

Use the Hub dashboard (Settings โ†’ System) or the CLI:

cihub app list # every Docker container on the host cihub app status # color-coded status + ports cihub app inspect <name> # ports, env vars, mounts cihub status # Hub stack health + networking

Direct Docker commands also work:

docker ps # running containers docker compose ls # compose projects docker system df # disk usage by images/volumes

Cleaning up Docker state

Over time, unused images and stopped containers consume disk space.

Safe cleanup (unused resources only)

docker system prune # stopped containers, unused networks docker image prune # dangling images only docker system df # check usage first

Aggressive cleanup (re-downloads images later)

docker system prune -a # all unused images

docker system prune -a removes cached images. Apps re-pull on next start, which can take time and bandwidth. Never add --volumes: it deletes named volumes, including ci_hub_pgdata, which holds Hubโ€™s own database.

Full Hub reset

To return Hub to a first-time state, use one of these. Each one deletes your operators, installed apps, registration, and local app data.

  • Settings โ†’ System โ†’ Factory reset Hub. You confirm by typing the deviceโ€™s name. Use this while Hub is running.
  • cihub reset --yes from a terminal, for when the Hub API is down. Run cihub reset --dry-run first to see the apps, containers, and folders it would remove. Without --yes, the CLI asks for confirmation.

A reset is destructive and permanent. Back up important app data first. See Backup and restore.

Removing Cloudflare tunnel credentials

If you unpair from your CI Account or need to reset remote access, Hub clears the tunnel token during registration reset. You can also remove it manually:

  1. In the Hub dashboard: Settings โ†’ Network โ†’ This Hub in your account โ†’ Reset this Hub only. This clears the Hubโ€™s pairing. The Portal keeps the device, its web addresses, and its apps until an owner or admin deletes them there.
  2. On disk: delete the token file in the tunnel folder next to your data root, for example ~/.local/share/tunnel/token on Linux. See Folder structure.
  3. Restart the Hub stack: cihub down && cihub up prod --detached

Hub starts the cloudflared container only for a paired Hub, when the tunnel folder holds both a token and a registration.json file. After you remove the credentials, the container stays stopped until you pair again and your CI Account provisions a new tunnel.

Hub stack containers

The Hub itself runs as a Docker Compose project. Typical containers include:

ContainerRole
ci-hubBackend API + dashboard (NestJS + React)
ci-hub-dbPostgreSQL database
ci-hub-queueRabbitMQ message queue
traefikReverse proxy and TLS
hub-tailscaleTailscale sidecar. It runs only when you set an auth key or the sidecar holds a saved Tailscale login; cihub also keeps it off when PRIVATE_VPN_USER_DISABLED=true
cloudflaredCloudflare tunnel. It runs only when Hub is paired with your CI Account

App containers are separate compose projects managed alongside the Hub stack. Older stacks used the names ci-os-hub and ci-os-hub-queue, which still resolve as network aliases.

Leaving without lock-in

Every app runs as standard Docker Compose. If you ever stop using Hub, your containers and volumes remain on disk. Each appโ€™s rendered compose file is apps/<store>/<app>/docker-compose.yml and its environment is app-data/<store>/<app>/app.env, both under your data root. You can start an app manually by running docker compose --env-file <app.env> -f <docker-compose.yml> up -d.

Last updated on