From e10585a071b31c94b24a93edfb87503eb816ddf1 Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Mon, 21 Sep 2026 23:23:31 +0200 Subject: [PATCH] fix(docker): home dir e cache uv per l'utente non privilegiato (#38.1) useradd senza -m lascia l'utente app senza $HOME: uv run nel CMD non trova dove scrivere la sua cache. Aggiunto -m a useradd in Dockerfile, Dockerfile.frontend e Dockerfile.vision, e UV_CACHE_DIR=/tmp/uv-cache esplicito (indipendente da $HOME). docs/DEPLOYMENT.md: nuova sezione sull'aggiornamento di un'installazione esistente, con il chown del volume upload_data ereditato da versioni precedenti. Co-Authored-By: Claude Sonnet 5 --- Dockerfile | 9 +++++++-- Dockerfile.frontend | 9 +++++++-- Dockerfile.vision | 7 ++++++- docs/DEPLOYMENT.md | 24 ++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 5 deletions(-) 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