diff --git a/Dockerfile b/Dockerfile index 42c1159..bda9e37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ shared-mime-info \ && rm -rf /var/lib/apt/lists/* -# Non-root user the app runs as at runtime. -RUN useradd -u 10001 app +# Non-root user the app runs as at runtime. -m creates a home dir: `uv run` +# in the CMD below writes its cache under $HOME, and without one it has +# nowhere writable to put it. +RUN useradd -m -u 10001 app +# Independent of $HOME regardless: keeps the cache path explicit and writable +# by the app user even if the home directory assumption ever changes. +ENV UV_CACHE_DIR=/tmp/uv-cache WORKDIR /app diff --git a/Dockerfile.frontend b/Dockerfile.frontend index 027eb88..4715cc3 100644 --- a/Dockerfile.frontend +++ b/Dockerfile.frontend @@ -18,8 +18,13 @@ FROM python:3.11.16-slim AS base # uv from the official slim image (fast Python package manager). COPY --from=ghcr.io/astral-sh/uv:0.10.9 /uv /uvx /usr/local/bin/ -# Non-root user the app runs as at runtime. -RUN useradd -u 10001 app +# Non-root user the app runs as at runtime. -m creates a home dir: `uv run` +# in the CMD below writes its cache under $HOME, and without one it has +# nowhere writable to put it. +RUN useradd -m -u 10001 app +# Independent of $HOME regardless: keeps the cache path explicit and writable +# by the app user even if the home directory assumption ever changes. +ENV UV_CACHE_DIR=/tmp/uv-cache WORKDIR /app diff --git a/Dockerfile.vision b/Dockerfile.vision index 7cfffed..a2c9e84 100644 --- a/Dockerfile.vision +++ b/Dockerfile.vision @@ -10,7 +10,12 @@ COPY --from=ghcr.io/astral-sh/uv:0.10.9 /uv /usr/local/bin/uv # Non-root user the app runs as at runtime. Same UID as the server's Dockerfile # so both containers agree on ownership of the shared uploads volume (point 13). -RUN useradd -u 10001 app +# -m creates a home dir: `uv run` in the CMD below writes its cache under +# $HOME, and without one it has nowhere writable to put it. +RUN useradd -m -u 10001 app +# Independent of $HOME regardless: keeps the cache path explicit and writable +# by the app user even if the home directory assumption ever changes. +ENV UV_CACHE_DIR=/tmp/uv-cache WORKDIR /app COPY pyproject.toml uv.lock ./ diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index ebbe539..efc40d7 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -435,6 +435,30 @@ docker compose -f docker-compose.yml logs -f server docker compose -f docker-compose.yml down ``` +### Aggiornare un'installazione esistente + +Le immagini precedenti creavano l'utente non privilegiato senza una home +directory (`useradd -u 10001 app`), e il volume `upload_data` che ne è +risultato appartiene a `root`. Le immagini attuali creano l'utente con +`-m` e impostano `UV_CACHE_DIR=/tmp/uv-cache`, ma questo non cambia da solo +la proprietà di un volume già esistente: se si riparte con le nuove immagini +su un volume creato da una versione precedente, il container `server` non +riesce a scrivere sotto `/app/uploads`. + +Prima del primo avvio con le nuove immagini, va quindi corretta la proprietà +del volume: + +```bash +docker compose -f docker-compose.yml run --rm --user root --entrypoint chown server -R 10001:10001 /app/uploads +``` + +(sostituire `docker-compose.yml` con `docker-compose.dev.yml` per +un'installazione di sviluppo/on-premise). Il comando usa il servizio +`server` perché è quello che monta il volume `upload_data` in lettura e +scrittura; il worker di visione lo monta in sola lettura e non ne ha +bisogno. Un'installazione nuova, che parte da un volume vuoto, non richiede +questo passo. + --- ## SSL/TLS