FROM python:3.13-alpine3.23 AS builder ENV UV_SYSTEM_PYTHON=1 COPY pyproject.toml . RUN pip install uv && uv pip install -r pyproject.toml && pip uninstall -y uv FROM python:3.13-alpine3.23 COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages WORKDIR /code # Set user and group ARG user=apps ARG uid=1001 ARG gid=1001 RUN addgroup -S ${user} && adduser -S ${user} -G ${user} -u ${uid} -s /bin/sh # pango + ttf-dejavu: librerías nativas que weasyprint necesita en tiempo de # ejecución (no al instalar el paquete Python, que ya funciona sin esto) para # poder generar el PDF del patrón (ver PatternPdfView); sin fuentes # instaladas, Pango no tiene nada que medir/dibujar y WeasyPrint termina # haciendo segfault en vez de fallar con un error legible. # gettext: msgfmt, para compilemessages en build.sh. # Sin gcc ni libpq-dev: psycopg[binary] (ver pyproject.toml) trae su propio # libpq ya compilado dentro de la wheel (hay una para musllinux_x86_64, # justo lo que necesita esta imagen), así que no hace falta ni compilar # nada ni que psycopg encuentre una libpq del sistema en tiempo de # ejecución. Probado a mano (build+run real): "import psycopg" funciona # sin ninguno de los dos. RUN apk add --no-cache gettext pango ttf-dejavu RUN chown -R ${user}:${user} /code COPY --chown=${user}:${user} . /code # libstdc++/libgcc: solo los necesita en tiempo de ejecución el binario de # Tailwind (ver build_pattern_detail_css, dentro de build.sh) para generar # pattern-detail.css, no la app en sí; "--virtual" + "apk del" en la misma # capa para que no se queden en la imagen final (build.sh además borra el # propio binario de Tailwind al terminar, ver scripts/build.sh). build.sh # se ejecuta como ${user} (no root), aunque este RUN empiece como root # para poder instalar/desinstalar el paquete virtual. RUN apk add --no-cache --virtual .tailwind-runtime libstdc++ libgcc \ && su ${user} -c "sh ./scripts/build.sh" \ && apk del .tailwind-runtime USER ${user} CMD ["sh", "./scripts/run.sh"]