Skip to content

Latest commit

 

History

History
164 lines (110 loc) · 6.82 KB

connecting.md

File metadata and controls

164 lines (110 loc) · 6.82 KB

🔗 Connecting

Four ways into the container, landing as dev in the same bind-mounted /home/dev — laptop and workstation ~/projects differ. Normal work goes through herdr; ssh devbox covers one-off commands and tunnels, Moshi covers the phone, and ./bin/devbox shell is the recovery route.

Related: Installation · Git Identities · Toolchain · Networking


🗺️ Routes

Route From Use it for
herdr Laptop Normal work: survives client exit, network loss
ssh devbox Laptop One-off commands, scripts, tunnels, rsync, git
Moshi Phone Watching, steering an agent away from the desk
./bin/devbox shell Workstation Recovery when SSH or the network is broken

🪟 herdr panes

herdr                    # select "Devbox" in the sidebar

A pane opens a login shell in /home/dev, running server-side after detach or quit — lid-close or a killed client won't interrupt a build, clone, or agent; reconnecting restores it.

herdr requires the pinned binary at /usr/local/bin/herdr — background connections get only the default non-interactive SSH PATH, so it's missing from ~/.local/bin.

🔑 ssh devbox

devbox is an SSH config alias, not a shell alias (Installation). Expands to:

ssh -p 2223 -l dev -o IdentitiesOnly=yes -i ~/.ssh/devbox.pub <workstation>

Interactive, then one-shot; quote so ~ expands remotely, not on the laptop:

ssh devbox
ssh devbox 'cd ~/projects/devbox && git status -sb'

Anything reading ~/.ssh/config honours it: scp, rsync, git, ssh -L.

Add -A to forward the laptop's 1Password agent for one connection — manual git needs it (clone, fetch, push, signed commit; agent sessions use HTTPS instead — Git Identities):

ssh -A devbox

Note

Plain ssh devbox (no -A), herdr panes and ./bin/devbox shell never forward the agent — manual git fails, on purpose: Git Identities.

🧯 ./bin/devbox shell

ssh <workstation> 'cd ~/devbox && ./bin/devbox shell'   # docker compose exec -it devbox bash -l

This bypasses the container's sshd, working even if authorized_keys, the host key, or Tailscale is broken.

📱 Moshi on a phone

Moshi's an SSH client: host <workstation>, port 2223, user dev, container-authorized key.

Important

Add the phone's key to DEVBOX_EXTRA_AUTHORIZED_KEYS in .env on the workstation, not via Easy Pair — the entrypoint rebuilds authorized_keys from GitHub plus that variable each start, erasing direct edits at the next ./bin/devbox up.

Notifications, lock-screen approvals, and transcript view need moshi-hook, which bootstrap installs and the entrypoint starts. One pairing step activates it — Toolchain.

📥 Cloning a repo

Clone inside the container, agent forwarded, target directory picking the identity — the remote is the same plain GitHub URL either way:

ssh -A devbox
git clone git@github.com:<your-github-username>/<repo> ~/projects/<repo>       # default identity
git clone git@github.com:<org>/<repo> ~/projects/work/<repo>                   # non-default, org in its `orgs`

Full rules — how the ssh tag and the hasconfig: org include pick a non-default identity's key and author, how agent sessions authenticate without either — in Git Identities.

🌐 Reaching a dev server

Dev servers aren't published — forward the port over the existing SSH connection:

# in a devbox pane
pnpm dev                                  # or python3 -m http.server 5173

# on the laptop
ssh -N -L 5173:localhost:5173 devbox &
curl -sS -o /dev/null -w '%{http_code}\n' localhost:5173    # 200

AllowTcpForwarding yes in container/sshd_config enables this. Add more -L pairs for more ports; no docker-compose.yml changes.


❓ FAQ

Do I clone on the laptop, the workstation, or in the container?

In the container: the bind mount makes a repo cloned in a herdr pane visible over ssh devbox and ./bin/devbox shell, surviving docker compose restart.

Is ssh devbox reachable from outside the Tailnet?

No — the port publishes only on the node's Tailscale address and 127.0.0.1 (Networking).

Why does git push fail over plain ssh devbox?

The devbox holds no private key; -A forwards the laptop's 1Password agent — see Git Identities.

Too many authentication failures — why?

The agent offered more than six keys before the right one; IdentitiesOnly yes plus IdentityFile ~/.ssh/devbox.pub in Host devbox fixes it.

Host key verification failed after a rebuild?

Shouldn't happen: the host key lives in /home/dev/.ssh/host/'s bind mount, surviving rebuilds. Wiped data dir? Remove the stale line: ssh-keygen -R '[<workstation>]:2223', reconnect.

Moshi connected to my laptop and 1Password asked to use the Devbox Laptop key — why?

Moshi's laptop host runs herdr, and every herdr client connects every saved machine itself: the new client opens its own ssh devbox for the Devbox machine, and that is what 1Password is approving. Approve, and that client shows the devbox through the laptop; deny, and only its Devbox entry sits at Attention — Local panes, the desktop client and a direct phone → devbox connection are unaffected. The direct route above involves neither the laptop nor 1Password, which is why it is the recommended one.

Which tools resolve in a non-interactive ssh devbox '<cmd>'?

All of them: pinned binaries in /usr/local/bin (node/npm/npx/corepack/pnpm, symlinked from /opt/nvm); ~/.bashrc.d/devbox.sh loads above Ubuntu's non-interactive early return, putting ~/.local/bin (OMP's and Claude Code's install dir) on PATH, and ~/.bash_profile reasserts that order for login shells, where ~/.profile would re-prepend ~/.local/bin ahead of the agent launchers. Verify both routes: ssh devbox 'command -v omp claude node pnpm herdr' and ssh devbox 'bash -lc "command -v omp claude"' — the second must print ~/.local/libexec/devbox-agent/omp and …/claude, the launchers.

Can I use VS Code / JetBrains Remote?

Yes — point Remote-SSH at devbox: an OpenSSH server, sftp enabled.

Does a pane keep running if the container restarts?

No — the herdr server dies with the container; only the filesystem survives. herdr restores the shape, but running processes are gone.