Server and VPS setup
Install the Companion on a dedicated Linux server account and keep it running, or give agents a Docker environment.
On this page
Install the Companion under a dedicated account on a Linux server and pair it as a device in Cabane. On a server, agents can keep working while your own computer sleeps. They work as that account, with its files, tools and signed-in accounts, without asking before each action.
To give them less, use a harness sandbox or a Docker environment, described in Give agents their own environment. For a Windows server, follow Windows setup.
Before you start
Use a dedicated account that is not root, with a systemd user service and administrator permission to enable linger. Keep that account's files and credentials separate from your personal ones. Have your Cabane workspace open and the account or provider credentials you plan to use with Claude Code, Codex or OpenCode.
Run every command on this page in that account's shell, except where a step opens a second terminal.
Pair it
If you do not have a Cabane workspace yet, create it first. In Cabane, choose the gear at the bottom of the sidebar to open the workspace's Settings, then choose Devices → Set up a new device. The same dialog is available from Connect AI during workspace setup, and Your settings → Devices → Add a device pairs a device without adding it to a workspace.
Copy the line under With the installer and run it in the dedicated account's shell:
curl -fsSL https://cabane.ai/install.sh | bash
In a Windows browser, that line comes second, under In WSL · With the installer: run it in the dedicated account's shell all the same, not on your Windows computer.
The installer supplies Node and the Companion under ~/.cabane, then runs cabane setup, which prints a code and a link:
◇ Pair this device
│ Enter this code in Cabane, or press Return to open the page:
│
│ WXYZ-2345
│ https://app.cabane.ai/pair/enter-code
│
◒ Waiting for you to confirm in Cabane… (the code is good for 15 minutes)
In the dialog you opened in Cabane, type the code into Code from the terminal. Cabane shows which device asked: its name, platform and how long ago it asked. Choose Confirm. A few seconds later the terminal says the device is paired: it's paired to your account, and the workspace's dialog adds it to that workspace. A code works once and expires after 15 minutes; the terminal prints a fresh one when it does. Follow any PATH instruction the installer prints. The page the terminal's link opens also takes the code, but pairs the device to your account only; a device paired there is added to a workspace afterwards with Add a device in that workspace's Settings → Devices.
On a first interactive setup, if none of Claude Code, Codex or OpenCode is usable, setup asks “Cabane needs one of them. Which will you set up?” Choose the one you intend to use. Setup prints installation and sign-in lines for that choice; the complete commands are in the next step. Needs sign-in is expected until you sign in.
Sign in without a browser
For Claude Code and Codex, open the printed URL in your personal device's browser and return any code requested by the terminal. Sign in under the dedicated account even if you already use the same provider elsewhere.
Claude Code:
curl -fsSL https://claude.ai/install.sh | bash
export PATH="$HOME/.local/bin:$PATH"
claude auth login
Codex: use the Node installation supplied by the Companion.
export PATH="$HOME/.cabane/node/bin:$PATH"
npm i -g @openai/codex
codex login --device-auth
Use --device-auth even if setup prints plain codex login. Device authentication must be enabled for your ChatGPT account or workspace.
OpenCode:
curl -fsSL https://opencode.ai/install | bash
Open a separate terminal logged in to that same account so it picks up the PATH change. In that new shell, run:
opencode auth login
Choose your provider and follow its credential instructions. Setup's printed lines don't include this sign-in. Then start its server in this separate terminal:
opencode serve --port 4096
Keep the terminal open while using OpenCode. The Companion's service does not supervise this server.
In the dedicated account's original shell, check that your chosen harness shows connected:
cabane status
For other authentication options, see signing in without a browser and when to use a token.
Keep it running and update
Install the Companion's systemd user service. Service installation prints the linger reminder; enabling linger lets it run after logout and reboot. Run in the dedicated account's shell:
cabane service install
sudo loginctl enable-linger "$USER"
cabane service status
The service enables automatic updates, which can restart the Companion during a turn. After a reboot, check cabane service status in that account's shell and run cabane start if the Companion is stopped. For OpenCode, also open a separate terminal logged in to the same account and run opencode serve --port 4096 again. Keep that terminal open while using OpenCode.
If you run the Companion without its service, use cabane update in the dedicated account's shell when no agent is working.
Stop or disconnect
In the dedicated account's shell, cabane stop stops the Companion and any running turns, cabane start starts it again, and cabane service uninstall disables automatic startup. Stop a separate OpenCode server with Ctrl+C in its terminal.
cabane logout clears pairing credentials while keeping your configuration and the device record in Cabane. For deactivation, token rotation, removal or pairing a removed device again, see Devices.
Give agents their own environment
Recommended for agents reading untrusted input, such as public websites or inbound mail, and for a server a team shares. Agent access compares the levels.
- A harness sandbox. Install directly as above and follow Harness sandboxes to configure the restrictions you want.
- A Docker environment. Agents work inside a container with its own tools and sign-ins, and see only the work folder you share. Follow the recipe below instead of steps 1 to 3.
Docker environment
The example below keeps credentials across container replacement and shares one work folder from the host. It works on a server or with Docker Desktop. Keep the host and Docker running while agents work.
Install Docker with Docker Compose, and use an account other than root that can run Docker. For host shell commands, use your server's shell. With Docker Desktop, use macOS Terminal or a WSL shell. Run these commands from the cabane-device folder you create below, except where the recipe explicitly takes you inside a container.
Prepare the Docker environment
In the host shell, create a folder for the device, a work folder and a .env file recording your account's user ID:
mkdir cabane-device
cd cabane-device
mkdir work
printf 'LOCAL_UID=%s\n' "$(id -u)" > .env
Create the following three files in cabane-device.
Dockerfile installs the Companion, Claude Code, Codex and OpenCode. It runs them as a non-root user whose ID matches your host account, so they can write to the shared work folder.
FROM node:22-bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl git nano \
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g @cabane/companion @anthropic-ai/claude-code @openai/codex opencode-ai
ARG LOCAL_UID=1000
RUN test "${LOCAL_UID}" -gt 0 && usermod -u "${LOCAL_UID}" node && chown -R node:node /home/node
USER node
WORKDIR /work
RUN cabane --version && claude --version && codex --version && opencode --version
compose.yaml keeps the whole container home in a named volume and mounts the host's work folder at /work. Changes in /work change the host files.
x-device: &device
build:
context: .
args:
LOCAL_UID: ${LOCAL_UID:-1000}
init: true
restart: unless-stopped
volumes:
- companion-home:/home/node
- ./work:/work
services:
companion:
<<: *device
hostname: cabane-docker
environment:
CABANE_COMPANION_SUPERVISED: "1"
command: ["cabane", "start", "--foreground"]
opencode:
<<: *device
profiles: ["opencode"]
network_mode: "service:companion"
command: ["opencode", "serve", "--hostname", "127.0.0.1", "--port", "4096"]
volumes:
companion-home:
.dockerignore limits the build context to the Dockerfile, keeping your work and credentials out of the image build:
*
!Dockerfile
If you plan to use OpenCode, append this setting to .env from the host shell:
printf 'COMPOSE_PROFILES=opencode\n' >> .env
The saved setting includes OpenCode in later Compose commands. Its server shares the Companion's network and listens on 127.0.0.1:4096 inside it. This recipe publishes no ports and mounts no Docker socket.
Build the image from the host shell:
docker compose build
You build and maintain this image locally. To use specific package versions, add @VERSION to their names in the Dockerfile. Add any other tools agents need there too, so rebuilding restores them.
Pair the Docker environment
Open the workspace's Settings → Devices → Set up a new device, as in step 1. If the line under With npm · @cabane/companion carries --server and an address, your Cabane isn't the hosted one: note that address for the command below.
In the host shell, from cabane-device, open an interactive shell in a temporary container:
docker compose run --rm --no-deps companion sh
Now inside the container, run setup, adding --server ADDRESS only for a Cabane that isn't the hosted one:
cabane setup
Setup prints a code and waits. Enter the code in the dialog and choose Confirm; the container's terminal reports the pairing a few seconds later. If setup asks “Cabane needs one of them. Which will you set up?”, choose Claude Code, Codex or OpenCode. The image already includes all three tools: skip the installation, sign-in and server commands setup prints. Continue below to start the persistent services, then sign in from the host shell as described in the next section. If you chose OpenCode, its Compose service runs the server. Pairing itself does not sign you in.
After pairing, expect to find this device as cabane-docker in Cabane. See Devices to rename it.
Setup starts the Companion in the temporary container. When it returns to the prompt, run these commands inside the container to turn off automatic updates, stop that Companion and leave the shell:
cabane update --auto off
cabane stop
exit
Back in the host shell, start the services:
docker compose up -d
The persistent home keeps the pairing. Later starts reuse it without another setup code. With automatic updates off, update the Companion by rebuilding the image as described in Keep the container running and update.
Sign in inside the container
For a direct installation on the server account, use Sign in without a browser. The commands below run inside Docker.
Sign in inside this environment even if you use the same account on your personal device. For Claude Code and Codex, open the printed URL yourself in your personal device's browser, complete sign-in there, and return any code requested by the terminal.
The Dockerfile has already installed the sign-in commands. Run the one you need in the host shell, from cabane-device.
Claude Code:
docker compose exec companion claude auth login
Codex:
docker compose exec companion codex login --device-auth
Use --device-auth even if setup prints plain codex login. Device authentication must be enabled for your ChatGPT account or workspace.
OpenCode:
docker compose exec companion opencode auth login
Choose your provider and follow its credential instructions. The OpenCode service uses the same home as the Companion, so it can use the credentials saved by this command. Make sure you enabled its profile in Prepare the Docker environment.
After signing in, check the device from the host shell:
docker compose exec companion cabane status
Check that the harness you want the agent to use shows connected. You will choose that harness for the agent when assigning them to this device. The persistent home keeps your sign-ins across container replacement.
Keep the container running and update
The Compose file restarts the services unless you explicitly stop them. Keep Docker running and the host awake. After a host restart, start Docker and run these commands in the host shell, from cabane-device:
docker compose up -d
docker compose exec companion cabane status
To update the installed packages, wait until no agent is working. Then rebuild and replace the containers from the same host shell and folder:
docker compose build --pull --no-cache
docker compose up -d --force-recreate
docker compose exec companion cabane status
Rebuilding fetches the package versions specified by your Dockerfile, or the latest published versions where you have not pinned them. Replacing containers interrupts active work; the home volume and shared work folder survive.
Stop, pause or remove the container
Use the host shell in cabane-device:
| Command | Result |
|---|---|
docker compose stop | Stops the services while keeping their containers and storage. |
docker compose up -d | Starts the services again. |
docker compose down | Removes the containers and keeps the home volume and host work folder. |
Adding --volumes to docker compose down deletes the home volume, including pairing credentials and sign-ins. Keep the volume when updating, rotating a token or pairing a removed device again.
For deactivation or removal in Cabane, see Devices. The next two sections cover recovery inside this Docker environment.
Rotate a Docker device’s token
When no agent is working, follow Devices to rotate the token in Cabane. Cabane reveals the replacement once.
In the host shell, from cabane-device, stop the services and open the saved configuration in an editor:
docker compose stop
docker compose run --rm --no-deps companion nano /home/node/.cabane/config.json
In the editor, replace only the value of deviceToken, keeping its quotation marks and the rest of the file. Paste the token into this file, never into a shell command or .env. Save with Ctrl+O, press Enter, then exit with Ctrl+X.
Back in the host shell, restart and check the device:
docker compose up -d
docker compose exec companion cabane status
Pair a removed Docker device again
If you removed the device from your account in Cabane, clear its old pairing before pairing a new device. Keep the home volume to retain your configuration and provider sign-ins.
Open Set up a new device in Cabane, as in Pair the Docker environment. Then run in the host shell, from cabane-device:
docker compose stop
docker compose run --rm --no-deps companion sh
Now inside the container, run:
cabane logout
Confirm the logout when asked. It clears the old Cabane pairing while keeping your configuration and provider sign-ins. Then, still inside the container, run setup again, with --server ADDRESS only for a Cabane that isn't the hosted one, and enter the code it prints in the dialog:
cabane setup
When setup returns to the prompt, run inside the container:
cabane update --auto off
cabane stop
exit
Back in the host shell, restart and check the new device:
docker compose up -d
docker compose exec companion cabane status
Assign agents to the container
When you assign an agent to this device in Agent execution settings, set What they can reach → Starts in to /work. This makes the host's shared work folder their starting folder inside the container.
A fresh environment every session
To create a fresh environment for each session, use the Companion's runner.command interface with your own wrapper. The wrapper must pass through the command, standard input and environment, and handle cleanup.
Choose what to retain between sessions. Mounted work and explicitly retained credentials can outlive the environment. The Docker recipe on this page keeps a persistent home across sessions.
Back to Quick start
Return to Quick start: check the device. Follow Agent execution settings to assign your agent to the device you paired here and choose a harness that shows connected on that device.