code-server + tailcat compose for an iLands sandbox (no Caddy). Sandbox sleeps after ~5 min idle.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-02 07:47:39 +00:00
skills/tailcat Add tailcat SKILL.md (gotchas + sandbox vs hardware split) 2026-10-02 07:47:39 +00:00
.env.example Initial public recipe: code-server + tailcat, no Caddy. 2026-10-02 02:37:01 +00:00
docker-compose.yml Initial public recipe: code-server + tailcat, no Caddy. 2026-10-02 02:37:01 +00:00
README.md Add tailcat SKILL.md (gotchas + sandbox vs hardware split) 2026-10-02 07:47:39 +00:00

code-server + tailcat (no Caddy)

Small stack for giving an ilander (or yourself) a browser IDE on a sandbox host, reachable from your laptop through Tailscale tailcat.

Verified 2026-10-02 on Debian host docker. Caddy was in the first pass and is not needed: tailcat can serve code-server's 8080 directly.

Files

  • docker-compose.yml — two services, host network
  • .env.example — copy to .env

What it mounts

Host In container
named volume meka-code-home /home (coder home, persists)
/workspace (or $WORKSPACE_DIR) /workspace
/ (or $SANDBOX_ROOT) /mnt/sandbox so /etc is /mnt/sandbox/etc
/var/run/docker.sock same, plus privileged: true

Run

cp .env.example .env
# edit PASSWORD and TAILCAT_AUTHKEY
docker compose up -d
docker logs meka-tailcat

Copy the tailcat address from the logs.

On your machine:

tailcat forward <that-address>

Then open http://127.0.0.1:8080/ (not 18080). Login is PASSWORD.

Gotchas we actually hit

  1. Image tag: git.merith.xyz/oci/code-server:latest 404'd. :nightly pulled.
  2. Homebrew first boot can fail once, then recover. Ignore the first git noise.
  3. Permission: mkdir /home/coder/.cache/Microsoft can EACCES. That kills the editor UI while the process stays up. Fix: docker exec -u 0 meka-code-server chown -R coder:coder /home/coder.
  4. Dead page usually means the local forward dropped, not the containers. Both are unless-stopped. Re-forward the last address.
  5. Do not use a pipe-mode tailcat token. It times out. Use a real serve auth key.
  6. Host docker, not nested workspace docker. User may need sudo if not in the docker group.

Teardown

docker compose down
docker volume rm meka-ide_meka-code-home   # optional, wipes editor home

Hard limit: the sandbox sleeps

This stack only stays useful while the agent's sandbox is awake.

On iLands, the sandbox host is an active conversation. If the agent is idle, the sandbox sleeps after about 5 minutes. unless-stopped keeps containers alive on that host, but when the host itself sleeps, docker, code-server, and tailcat go with it. Forwarding from your laptop then dies because there is nothing listening.

To keep the IDE up you need an active conversation with the agent (and that burns tokens). This is not a 24/7 VPS recipe. Do not treat restart: unless-stopped as "it will still be there in the morning."

If you want always-on, run this on a real machine you control, not inside an iLands sandbox.

What this is not

Not the Forgejo + runner stack. That lives in ilander-git-home. This is only the IDE tunnel.

Agent skill

Gotchas we actually hit (pipe-mode vs forward, address-is-credential, sandbox sleep) live in skills/tailcat/SKILL.md. Read that before running the binary. No live addresses in this repo.