Set up a GPU server
Deploy the headless cradle-server on a Linux GPU VM, bootstrap it, and connect a Cradle client.
For anything beyond a single laptop you run Cradle Server — the headless
cradle-server daemon. It holds the data, the connectors, and the inference,
while thin clients (the desktop app or the cradle CLI) drive it over an
authenticated HTTP API. This guide installs it on a Linux GPU VM.
Requirements
- Linux x86_64 (builds are
linux-x64). - Node 22 and pnpm (
corepack enable, ornpm install -g pnpm@9). - Root access for the installer and bootstrap.
- For GPU inference: NVIDIA drivers + CUDA toolkit. CPU-only works with no extra dependencies.
Install from S3 (curl flow)
The server/CLI bundle is published to the same downloads bucket as the desktop
app, under the cradle-cli prefix. The one-liner installer handles the rest:
curl -fsSL \
https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh \
| sudo shOverride defaults with environment variables:
curl -fsSL -o cradle-cli-install.sh \
https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh
sudo CRADLE_PORT=31416 CRADLE_DATA_DIR=/var/lib/cradle \
sh cradle-cli-install.shThe installer checks for Node 22 + pnpm, downloads the zip, extracts to
/opt/cradle, installs production dependencies, rebuilds native modules for the
target platform, and bootstraps the server.
Install without root
If you have no root on the box (a VM on someone else's hosting, a shared
account), run the same installer without sudo. It detects the missing
privileges and switches to rootless mode: everything goes under
~/.local/share/cradle, no systemd unit is installed, and the CLI is linked
into ~/.local/bin.
curl -fsSL \
https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh \
| shStart the server yourself:
~/.local/share/cradle/dist/server/index.js \
--data-dir ~/.local/share/cradle/data --port 31416 --bind 0.0.0.0To survive logout, add a user unit at
~/.config/systemd/user/cradle-server.service and enable lingering:
systemctl --user enable --now cradle-server
loginctl enable-linger $USER # if the host policy allows itRootless limits: the port must be above 1024 (31416 is fine), autostart on
reboot only works with lingering, and --user cradle does not apply — the
service runs as you.
Manual install (from the zip)
If you prefer to see each step, or you are on a locked-down host, do it by hand:
# 1. Resolve the current version and download the bundle
VERSION=$(curl -fsSL https://download.opencradle.ai/cradle-cli/latest/manifest.json \
| grep -o '"version": *"[^"]*"' | cut -d'"' -f4)
curl -fsSL -o cradle-cli-${VERSION}-linux-x64.zip \
https://download.opencradle.ai/cradle-cli/${VERSION}/cradle-cli-${VERSION}-linux-x64.zip
# 2. Extract to /opt/cradle
sudo mkdir -p /opt/cradle
sudo unzip -o cradle-cli-${VERSION}-linux-x64.zip -d /opt/cradle
# 3. Run the installer (creates the `cradle` user, installs prod deps,
# rebuilds native modules, installs the systemd unit)
cd /opt/cradle
sudo ./install.shBootstrap the server
Bootstrapping creates the data directory, initialises the SQLite database, and generates the first admin API key. This is operator-driven — you run it on the target host; nothing is pushed over SSH from a client.
sudo /opt/cradle/dist/cli/index.js server init \
--data-dir /var/lib/cradle \
--port 31416 \
--bind 0.0.0.0 \
--install-systemdWhat it does:
- Creates
--data-dirand fixes permissions. - Runs the server in bootstrap mode to initialise the DB and generate an
admin:*key. - Writes a systemd unit and runs
systemctl enable --now. - Waits for
/admin/health, then issues a scoped client key. - Writes
client-credentials.json(mode0600) into the data directory.
Running server init again on the same data directory is idempotent: it detects
the initialised DB and exits instead of minting a new admin key.
Where things live
Every path below depends on how you installed:
| root install | rootless install | |
|---|---|---|
| Install dir | /opt/cradle | ~/.local/share/cradle |
| Data and keys | /var/lib/cradle | ~/.local/share/cradle/data |
| Service | system systemd | systemctl --user |
sudo | required | never needed |
Managing the service
Root install — system systemd:
sudo systemctl start cradle-server
sudo systemctl enable cradle-server
sudo systemctl status cradle-server
sudo journalctl -u cradle-server -fRootless install — a user service. The --user flag is required in every
command, and sudo is never used:
systemctl --user start cradle-server
systemctl --user enable cradle-server
systemctl --user status cradle-server
journalctl --user -u cradle-server -fConnect a client
Collect the credentials from client-credentials.json in the data directory —
sudo cat /var/lib/cradle/client-credentials.json after a root install, plain
cat ~/.local/share/cradle/data/client-credentials.json after a rootless one.
Transfer them to the Cradle client through your secure channel, then log in:
cradle login --url http://<server>:31416 --key ck_live_...The CLI probes /admin/health to verify the connection and stores the profile
in ~/.cradle/cli-config.json.
Running the daemon directly
Outside of systemd you can run the server yourself:
cradle-server --port 31416 --data-dir ~/.cradle
cradle-server --bind 0.0.0.0 # listen on all interfaces
cradle-server --no-api-autostart # skip auto-enabling the API channelGraceful shutdown on SIGINT/SIGTERM stops channels, releases model runners,
and closes the database.
Remote GPU nodes
To offload heavy inference to a separate GPU box, configure a remote node. The CLI only stores configuration — it never pushes SSH commands; the operator runs them on the organisation's jump host:
cradle remote set \
--host gpu-1.local --user cradle \
--ssh-key-path /root/.ssh/gpu-1 \
--remote-port 8080 --model-path /models/qwen3-8b.gguf
cradle remote showThe node is then used by creating a model with provider=remote-gpu. For
multiple nodes, cradle remote pool probe health-checks them and
cradle remote pool plan prints an autoscaler plan — it never executes SSH or
cloud calls itself.
See the CLI reference for the full command catalogue and remote-server deployment for the closed-network flow.