Docker & 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 re-used 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). 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.
What Hub manages for you
When you install an app, Hub:
- Pulls the required Docker images
- Generates an
app.envfile from your form inputs and Hub settings - Creates Traefik routing so the app gets a local hostname (e.g.
nextcloud.ci.lan) - Starts the compose stack and tracks status via Server-Sent Events
When you uninstall, Hub stops containers and can optionally remove volumes depending on your choice.
Inspecting Docker state
Use the Hub dashboard (Settings β System) or the CLI:
cihub app list # all containers Hub knows about
cihub app status # color-coded status + ports
cihub app inspect <name> # ports, env vars, mounts
cihub status # Hub stack health + networkingDirect Docker commands also work:
docker ps # running containers
docker compose ls # compose projects
docker system df # disk usage by images/volumesCleaning 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 firstAggressive cleanup (re-downloads images later)
docker system prune -a # all unused imagesdocker system prune -a removes cached images. Apps will re-pull on next start, which can take time and bandwidth.
Full Hub uninstall-style wipe (cihub uninstall)
For a clean-slate during development or troubleshooting:
cihub uninstall --yesThis removes Hub Docker containers/volumes and clears Hub runtime/config/cache/state directories. Your choice of --yes is required β without it, the CLI asks for confirmation.
cihub uninstall is destructive. Back up important app data first. See Backup & Restore.
Removing Cloudflare tunnel credentials
If you unpair from Companion Portal or need to reset remote access, Hub clears the tunnel token during registration reset. You can also remove it manually:
- In the Hub dashboard: Settings β Companion Portal β Reset registration (or re-pair flow)
- On disk: delete the token file at
<ROOT_FOLDER_HOST>/tunnel/token - Restart the Hub stack:
cihub down && cihub up prod --detached
After removal, the Cloudflare tunnel container stops routing traffic until you pair again and Portal provisions a new tunnel.
Hub stack containers
The Hub itself runs as a Docker Compose project. Typical containers include:
| Container | Role |
|---|---|
ci-os-hub | Backend API + frontend (NestJS + React) |
ci-hub-db | PostgreSQL database |
ci-os-hub-queue | RabbitMQ message queue |
ci-hub-traefik | Reverse proxy and TLS |
hub-tailscale | Tailscale sidecar (when Private VPN is enabled) |
cloudflared | Cloudflare tunnel (when paired with Portal) |
App containers are separate compose projects managed alongside the Hub stack.
Leaving without lock-in
Every app runs as standard Docker Compose. If you ever stop using Hub, your containers and volumes remain on disk. You can start any app manually with docker compose up from its data directory.