From 8b1774130bb9de109f9ea99597f4348f334fbb27 Mon Sep 17 00:00:00 2001 From: Kayos Date: Wed, 6 May 2026 22:55:17 -0700 Subject: [PATCH] fix: bind /nix to /mnt/cache, NOT docker-managed volume A docker-managed named volume lives at /var/lib/docker/volumes/, which is INSIDE docker.img (a 200 GB loop file shared with all images, container layers, and every other docker volume on the host). The Plutarch + haskell-nix closure for Liqwid-Labs/agora is tens of GB. Running nix develop against agora ONCE was enough to fill docker.img to 100% (196/200 GB used, 2 GB free). Every container on Lucy was about to start failing writes. Recovery: kill nix process, docker compose down, free 66 GB of BuildKit cache via `docker builder prune -a`, switch /nix to /mnt/cache bind mount (88+ GB free on that pool, completely separate from docker.img). Bind mount caveat: bare bind to an empty host dir shadows the image's /nix install (the previous bug we caught with the named-volume fix). One-time seed required: mkdir -p /mnt/cache/appdata/crafting-table/nix chown 1000:1000 /mnt/cache/appdata/crafting-table/nix docker create --name ct-seed crafting-table:local docker cp ct-seed:/nix/. /mnt/cache/appdata/crafting-table/nix/ docker rm ct-seed After seed, the bind mount works because the host path has the nix tree already populated. Subsequent docker compose up -d picks up the populated /nix and `nix --version` works in-container. --- compose.yml | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/compose.yml b/compose.yml index 1c4324d..ce0f1cf 100644 --- a/compose.yml +++ b/compose.yml @@ -35,19 +35,32 @@ services: - /mnt/user/appdata/crafting-table/data:/data - /mnt/user/appdata/crafting-table/workspace:/workspace - /mnt/user/appdata/crafting-table/caches:/caches - # Nix store — Docker-managed volume (NOT bind mount) so the image's - # pre-installed /nix tree gets seeded into the volume on first up. - # A bare bind mount to an empty host dir would shadow the image's - # /nix and leave `nix` unfindable inside the container. - # Persists haskell-nix downloads (multi-GB Plutarch / IOG flake - # closures) across container rebuilds. - - crafting-table-nix:/nix + # Nix store — bind mount to /mnt/cache (88+ GB free) NOT a bare + # docker-managed volume. A docker-managed volume lives at + # /var/lib/docker/volumes/, which is INSIDE the docker.img loop + # file (200 GB allocated, shared with all images + container layers + # + every other volume). The Plutarch + haskell-nix closure is + # tens of GB; running nix develop against Liqwid-Labs/agora once + # was enough to fill docker.img to 100% and break every container + # on Lucy. Caught 2026-05-06 mid-build. + # + # Bind to /mnt/cache so Plutarch + haskell-nix closures live on + # the cache pool, not docker.img. Pre-seed the host path with the + # image's stock /nix install ONCE at container init (or by + # `docker create + docker cp` when the path is empty) — bare bind + # mount to an empty host dir shadows the image's /nix install. + # + # If the bind path is missing or empty when you `docker compose + # up -d` for the first time, do this once: + # mkdir -p /mnt/cache/appdata/crafting-table/nix + # chown 1000:1000 /mnt/cache/appdata/crafting-table/nix + # docker create --name ct-seed crafting-table:local + # docker cp ct-seed:/nix/. /mnt/cache/appdata/crafting-table/nix/ + # docker rm ct-seed + - /mnt/cache/appdata/crafting-table/nix:/nix networks: [sulkta] restart: unless-stopped -volumes: - crafting-table-nix: - networks: sulkta: external: true