Run Overhand on a server
Linux or Docker, reached through an SSH tunnel or your tailnet.
On a Linux server.
- The same installer Run the one command from Install over SSH, as the user the agents should work as. The same package runs on arm64 and x64.
- Kept running With systemd it's a user service, and linger keeps it up after you log out. Without systemd, run
overhand startagain after each reboot. On Linux has the commands. - Only on the server itself Overhand listens on 127.0.0.1, so nothing outside the server reaches it until you choose one of the ways in below.
- Check it
overhand doctorover SSH lists what's missing: an agent,ghand its sign-in, a place for secrets.
In Docker.
- Build the image There's no published image yet; build it from the repository:
git clone https://github.com/craftly-io/overhand.git && cd overhand docker build -t overhand . docker run -d --name overhand --network host --restart unless-stopped \ -v overhand:/home/overhand overhand - Host network, loopback only With
--network hostit listens on the server's own 127.0.0.1, like the plain install. Publishing a port with-preaches nothing, because inside the container it listens on loopback too. On Docker Desktop the host network is its VM's, so this setup is for a Linux server. - One volume It runs as the user
overhand, not root. Its home is the volume: Overhand's state, the agents you install, their sign-ins, GitHub's login and your projects. API keys go to a file only that user can read. - Day to day
docker psshows it healthy once it answers on its port. Run commands withdocker exec overhand overhand doctor; its log isdocker logs overhand. Another port:-e OVERHAND_PORT=4400. - Turning it off and updating Turn off in Overhand restarts the container;
docker stop overhandstops it. To update, pull the repository, build again, then remove the container and run it again. The volume keeps everything.
Reach it from your laptop or phone.
- An SSH tunnel From your laptop, then open http://127.0.0.1:4317:
ssh -N -L 4317:127.0.0.1:4317 you@your-server - The same port on both ends Overhand answers only to the address it serves on, so a tunnel from another local port gets refused.
- Counts as the server Through the tunnel your browser is the server's own: finish setup and add devices there.
- Tailscale for your phone On the server, serve Overhand on your tailnet, then add that https address in Settings โ Extra origins:
A request through it gets nothing until that device is paired: open Settings โ Phone through the tunnel and add the device there. See Phone and Access from anywhere.tailscale serve --bg --https=8443 http://127.0.0.1:4317 - Never the open internet Don't publish the port or put it behind a public proxy or Tailscale Funnel. The tunnel or your tailnet is the way in.
Agent sign-ins without a desktop.
- Setup shows the command No terminal window can open on a server, so setup shows the exact command to install an agent and sign it in. Run it over SSH; in Docker, inside the container:
docker exec -it overhand sh -c '<the command setup shows>' - Claude Code
claude auth loginprints a link. Open it on your laptop, sign in, and paste the code it gives you back into the terminal. - Codex Plain
codex loginwaits for your browser on the server's own port 1455. Runcodex login --device-authinstead, and enter the code it shows on your laptop. - GitHub
gh auth login --webshows a one-time code; enter it at github.com/login/device on any device. - An API key instead Add it in Settings โ Agent accounts. With no keyring on the server it goes to
OVERHAND_SECRETS_FILE, which the image sets. See Agents and accounts.