Files
codecraft/docs/MOVING.md
T

7.9 KiB
Raw Blame History

Moving CodeCraft to another host (Unraid)

This guide moves a running installation – Docker volume codecraft-data on the current host – to another Docker host that keeps its data in bind mounts, for example Unraid. The script scripts/move-server.sh does the work; this page explains what goes where, what to prepare and how to check and roll back.

What lives where

Part Contents Today (Docker volume) On the new host
Data database codecraft.db, config.toml (incl. API keys), daily backups codecraft-data:/data <dir>/data → /data
Agent installs the agent's home /data/home: toolchains (Rust, …), pip/pipx/npm/cargo packages, downloaded programs (~/opt), caches inside the volume <tools-dir>/home → /data/home
Users' homes homes of sandboxed users /data/users/<name>/home (their installs, git settings) inside the volume <tools-dir>/users → /data/users
Temporary files /tmp of agents, builds, downloads container layer <tools-dir>/tmp → /tmp
Workspace your projects WORKSPACE from .env --workspace path → /workspace
Image the program registry image registry image

The image never changes: the container runs without root (no apt, no sudo), so agents can only install into their home directory. With --tools-dir everything agents install or download lands on a separate disk (e.g. an SSD); the data folder keeps only the database, configuration and backups. If the tools disk is lost, agents simply install what they need again – nothing important is on it. (Backups contain the database and configuration, not the agent home.)

Sizes on 2026-11-09 for orientation: agent home 2.2 GB (of which downloaded programs 1.3 GB, Rust toolchain 0.8 GB), database/config/backups about 1.2 GB.

Before you start

On the new host (Unraid):

  • SSH with a key from the current host, without a password prompt. Check from the current host: ssh root@unraid true (no output, no question = fine).
  • docker, rsync and tar available (all three are on Unraid by default).
  • Docker Compose is optional: without it the script starts the container with the generated start.sh (Unraid: the "Docker Compose Manager" plugin adds Compose).
  • The tools disk is mounted, e.g. an SSD via Unassigned Devices under /mnt/disks/ssd.
  • Registry access: the image comes from git.familie-zink.org/zink/codecraft. If the pull is refused, run docker login git.familie-zink.org on Unraid once.

Decide:

Question Option Example
Folder for data, compose file and scripts target root@host:/dir /mnt/user/appdata/codecraft
Folder for agent installs and /tmp --tools-dir /mnt/disks/ssd/codecraft
Your projects --workspace /mnt/user/projects
Owner of files (the container runs as this user) --uid, --gid Unraid default 99/100 (nobody:users); today 1000/1000
Docker of the new host for agents and terminals --docker-sock bind mount of /var/run/docker.sock plus its group (see below)
Port and address --port, --bind 8787; 0.0.0.0 if the reverse proxy runs on another machine or in another Docker network, 127.0.0.1 if it runs on the same host with host networking

Moving

On the current host, in the repository folder (where .env is):

# 1. Look at the steps first (changes nothing)
scripts/move-server.sh root@unraid:/mnt/user/appdata/codecraft \
  --workspace /mnt/user/projects --tools-dir /mnt/disks/ssd/codecraft \
  --uid 99 --gid 100 --bind 0.0.0.0 --docker-sock --dry-run

# 2. Move (same command without --dry-run)
scripts/move-server.sh root@unraid:/mnt/user/appdata/codecraft \
  --workspace /mnt/user/projects --tools-dir /mnt/disks/ssd/codecraft \
  --uid 99 --gid 100 --bind 0.0.0.0 --docker-sock

What happens:

  1. Checks: docker/tar/rsync on the target; the target data folder (and home/, users/ in the tools folder) must be empty – the script never overwrites.
  2. Workspace, first pass with rsync while CodeCraft keeps running (the long part).
  3. Stops CodeCraft here. Running agents and terminals end. The container is only stopped, not removed.
  4. Data volume is streamed with tar over SSH into <dir>/data; with --tools-dir the agent home and the users' homes are then moved to the tools folder.
  5. Workspace, second pass: only what changed since step 2.
  6. Owner of data, tools and workspace set to --uid:--gid (needs root on the target).
  7. Writes <dir>/docker-compose.yml, <dir>/.env (your .env with the new paths, port and owner), <dir>/start.sh (the same as docker run, for hosts without Compose) and <dir>/docker/seccomp-sandbox.json.
  8. Starts the image CODECRAFT_VERSION from .env (Compose, else start.sh).
  9. Smoke test on the target (scripts/smoke-test.sh): health, version, web UI, terminal client download.

Afterwards:

  • Reverse proxy: point the proxy host for code.familie-zink.org (Nginx Proxy Manager) to the new host and port; keep WebSocket support on.
  • Check in the web UI: sign in, open a chat, check the status LEDs (providers, MCP servers), let an agent run git status in a project (credentials, identity), open a terminal tab. Models or MCP servers on the old host's LAN address or localhost need new addresses.
  • Clean up on the old host when everything works: docker rm codecraft, later docker volume rm codecraft-data.

Docker socket (--docker-sock)

With --docker-sock the container gets the new host's Docker: /var/run/docker.sock is bind mounted and the container joins the socket's group (the script reads its group id on the target). This is root-equivalent access to the host: whoever can start containers can mount any host folder.

  • Admins' agents and terminals (they run without sandbox) can use it.
  • Sandboxed users do not see the socket (the sandbox does not mount /var/run).
  • docker and docker-compose commands always need an approval, except in bypass mode.
  • The image contains the Docker CLI (static client); the daemon is the host's.

The current host has the same setup in its local docker-compose.override.yml (group 997).

Rollback

Nothing is deleted on the old host. On Unraid stop the new container (docker stop codecraft), on the old host start the old one (docker start codecraft) and point the reverse proxy back. Changes made on the new host in the meantime (chats, settings) are not in the old installation.

Running it on the new host

In <dir> on Unraid:

Task With Compose Without Compose
Update set CODECRAFT_VERSION in .env, then docker compose pull && docker compose up -d set CODECRAFT_VERSION in .env, docker pull …:<version>, then ./start.sh
Restart docker compose restart docker restart codecraft
Logs docker compose logs -f docker logs -f codecraft
Check bash smoke-test.sh http://127.0.0.1:8787 <version> same

Releases are published from the development machine with scripts/release.sh; the new host only pulls them.

Troubleshooting

  • data on the target is not empty: an earlier attempt left files. Move <dir>/data (and home/, users/ in the tools folder) away and run the script again.
  • Image pull refused: docker login git.familie-zink.org on the target, then cd <dir> && docker compose up -d (or ./start.sh).
  • Smoke test fails: docker logs codecraft on the target. The old installation is stopped but intact – docker start codecraft on the old host brings it back.
  • could not chown: the SSH user is not root; set the owner by hand (chown -R 99:100 <dir>/data <tools-dir> <workspace>).
  • Permission denied inside the container: data, tools and workspace must belong to the UID/GID in <dir>/.env.
  • Port already in use: change PORT in <dir>/.env and start again.