Files
TieMeasureFlow/Dockerfile.frontend
T
Adriano e10585a071 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 <noreply@anthropic.com>
2026-09-21 23:23:31 +02:00

61 lines
2.4 KiB
Docker

# TailwindCSS built in its own stage, from the official Node image, instead
# of `curl | bash` against nodesource inside the final image (point 2, C2).
FROM node:20.20.2-bookworm-slim AS tailwind-build
WORKDIR /app/flask_app
COPY src/frontend/flask_app/ ./
# Versione esatta, non `tailwindcss@3`. Con il vincolo aperto ogni ricostruzione
# dell'immagine poteva prendere una minor diversa e produrre un CSS diverso senza
# che nessuno l'avesse validato: per un sistema che produce evidenze per audit
# ISO 9001 / IATF 16949 è lo stesso problema che il punto 12 risolve per le
# librerie del browser. Aggiornarla è una decisione, non un effetto collaterale.
RUN npm install tailwindcss@3.4.19 && \
npx tailwindcss -i static/css/input.css -o static/css/tailwind.css --minify
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. -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
# Resolve Python deps from the project lockfile (only the `client` extra).
COPY pyproject.toml uv.lock ./
COPY .python-version ./
RUN uv sync --frozen --no-dev --extra client
# Copy the Flask app sources, then overlay the TailwindCSS build produced in
# the node stage above — the final image never installs Node.
COPY src/frontend/flask_app/ ./flask_app/
COPY --from=tailwind-build /app/flask_app/static/css/tailwind.css ./flask_app/static/css/tailwind.css
# Compile Flask-Babel translation catalogs.
WORKDIR /app/flask_app
RUN uv run --project /app pybabel compile -d translations && \
chown -R app:app /app
USER app
EXPOSE 5000
# Gunicorn behind Nginx/Traefik. Worker count and proxy trust kept in sync
# with the per-tablet rate-limiting fix (see V2.0.0 perf commit).
CMD ["uv", "run", "--project", "/app", "gunicorn", \
"--workers", "5", \
"--threads", "4", \
"--worker-class", "gthread", \
"--timeout", "60", \
"--bind", "0.0.0.0:5000", \
"--access-logfile", "-", \
"--forwarded-allow-ips", "*", \
"app:create_app()"]