diff --git a/deploy/compose.docker-sbx.yaml b/deploy/compose.docker-sbx.yaml index f9d012b9..baa5d5d2 100644 --- a/deploy/compose.docker-sbx.yaml +++ b/deploy/compose.docker-sbx.yaml @@ -3,21 +3,27 @@ # profile, to the sandboxd daemon on the host. This provider runs no secrets # proxy. sbx swaps the placeholders itself, and the exchange pushes each issuer # value into the sandbox through the sbx CLI. sandboxd runs as one user. The -# overlay mounts four things: the daemon socket, the sbx CLI of the host, the -# CLI auth store, and the workspace root. The mount of the host CLI keeps the CLI version and -# the daemon version equal. The auth store and the workspace root keep the -# same path inside and outside the container, because the daemon resolves -# paths on its own filesystem. The services run with the uid of the daemon -# owner (the deploy user). DRUKS_SBX_HOME is the home directory of that user. -# install.sh writes it to .env, and each compose command renders the same -# mounts, also from sudo or systemd. The docker.sock mount from the base -# stays: browser-login containers use the docker provider. +# overlay mounts the sbx CLI of the host, the directory of the daemon socket, +# the CLI cache, the CLI auth store, the CLI settings store, and the drukbox +# directory with the workspace root. The mount of the host CLI keeps the CLI +# version and the daemon version equal. The other mounts keep the same path +# inside and outside the container, because the daemon resolves paths on its +# own filesystem. The services run with the uid of the daemon owner (the +# deploy user). DRUKS_SBX_HOME is the home directory of that user. install.sh +# writes it to .env, and each compose command renders the same mounts, also +# from sudo or systemd. The docker.sock mount from the base stays: +# browser-login containers use the docker provider. x-sbx-rig: &sbx-rig user: "${DRUKS_UID:?set DRUKS_UID in .env — run install.sh}:${DRUKS_GID:?set DRUKS_GID in .env — run install.sh}" volumes: - - ${DRUKS_SBX_HOME:?set DRUKS_SBX_HOME in .env — run install.sh}/.local/state/sandboxes/sandboxes/sandboxd/sandboxd.sock:/run/sandboxd.sock - /usr/bin/sbx:/usr/local/bin/sbx:ro + # The mount holds the directory of the daemon socket, not the socket file. + # A daemon restart makes a new socket, and a file mount keeps the old one. + - ${DRUKS_SBX_HOME:?set DRUKS_SBX_HOME in .env — run install.sh}/.local/state/sandboxes/sandboxes/sandboxd:${DRUKS_SBX_HOME:?}/.local/state/sandboxes/sandboxes/sandboxd + # The CLI reads its feature flags from the cache. Without them, it sees + # the SSH endpoint of the daemon as off, and the gateway tunnel fails. + - ${DRUKS_SBX_HOME:?}/.cache/sandboxes:${DRUKS_SBX_HOME:?}/.cache/sandboxes # The auth store must be writable: the credential store takes a lock file # inside it (.posixage.lock) also for reads, and every create loads # registry credentials. A read-only mount fails each create. @@ -28,12 +34,15 @@ x-sbx-rig: &sbx-rig - ${DRUKS_SBX_HOME:?}/.drukbox:${DRUKS_SBX_HOME:?}/.drukbox # The image has no user with the deploy uid, and defaults that come from the -# home directory resolve nowhere. XDG_CONFIG_HOME points the sbx CLI to the -# mounted auth store. The workspace root is set here, and it cannot disagree -# with the mount above. +# home directory resolve nowhere. The XDG variables point the sbx CLI to the +# mounted directories. `sbx ssh proxy` finds the daemon socket through +# XDG_STATE_HOME only. The other commands use DOCKER_SANDBOXES_API. The +# workspace root is set here, and it cannot disagree with the mount above. x-sbx-env: &sbx-env XDG_CONFIG_HOME: ${DRUKS_SBX_HOME:?}/.config - DOCKER_SANDBOXES_API: unix:///run/sandboxd.sock + XDG_CACHE_HOME: ${DRUKS_SBX_HOME:?}/.cache + XDG_STATE_HOME: ${DRUKS_SBX_HOME:?}/.local/state + DOCKER_SANDBOXES_API: unix://${DRUKS_SBX_HOME:?}/.local/state/sandboxes/sandboxes/sandboxd/sandboxd.sock DOCKER_SBX_WORKSPACE_ROOT: ${DRUKS_SBX_HOME:?}/.drukbox/sbx-workspaces services: diff --git a/scripts/install.sh b/scripts/install.sh index fdacaf3d..5def84e5 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -163,13 +163,14 @@ main() { set_env_var COMPOSE_PROFILES "hosted,gateway" # The sbx mounts live in the home directory of the daemon owner. Write # the path to .env, and each compose command renders the same mounts, - # also from sudo or systemd. Create the writable bind source now. The - # engine would make it root-owned, and the deploy-uid services could - # not write the workspaces or the gateway host key. + # also from sudo or systemd. Create the writable bind sources now. The + # engine would make them root-owned, and the deploy-uid services could + # not write the workspaces, the gateway host key, or the sbx settings + # and cache. set_env_var DRUKS_SBX_HOME "$HOME" - mkdir -p "$HOME/.drukbox/sbx-workspaces" "$HOME/.config/sandboxes" + mkdir -p "$HOME/.drukbox/sbx-workspaces" "$HOME/.config/sandboxes" "$HOME/.cache/sandboxes" # sandboxd must run before the first compose command. A bind of a - # missing socket path makes a root-owned directory there, and that + # missing socket directory makes a root-owned directory there, and that # blocks the daemon itself. SBX_SOCKET="$HOME/.local/state/sandboxes/sandboxes/sandboxd/sandboxd.sock" if [ ! -S "$SBX_SOCKET" ]; then