# syntax=docker/dockerfile:1 # Builds the Fluent web components bundle; Node.js is not part of the runtime image. FROM node:24-slim AS frontend WORKDIR /frontend COPY portal/frontend/package.json portal/frontend/package-lock.json ./ RUN npm ci --ignore-scripts --no-audit --no-fund COPY portal/frontend/entry.js portal/frontend/build.mjs ./ RUN npm run build FROM python:3.13-slim AS builder COPY --from=ghcr.io/astral-sh/uv:0.13.1 /uv /usr/local/bin/uv ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy UV_PYTHON_DOWNLOADS=never WORKDIR /app RUN apt-get update \ && apt-get install -y --no-install-recommends build-essential libldap2-dev libsasl2-dev gettext \ && rm -rf /var/lib/apt/lists/* COPY pyproject.toml uv.lock .python-version README.md ./ RUN uv sync --frozen --no-dev --no-install-project COPY manage.py ./ COPY portal ./portal COPY --from=frontend /frontend/dist/fluent.js ./portal/static/vendor/fluent.js # Build-time only values so compilemessages and collectstatic can load settings; not used at runtime. RUN SECRET_KEY=build-time-only-value-not-used-at-runtime-000000 \ ALLOWED_HOSTS=localhost DATA_DIR=/tmp \ LDAP_SERVER=build.invalid LDAP_USER_OU_DN=build LDAP_BIND_DN=build LDAP_BIND_PASSWORD=build \ LDAP_CA_FILE=/app/README.md LDAP_PUBLISHER_GROUP_DN=build LDAP_ADMIN_GROUP_DN=build \ OIDC_ISSUER=https://build.invalid/ OIDC_CLIENT_ID=build OIDC_CLIENT_SECRET=build \ PUBLIC_BASE_URL=https://build.invalid \ SMTP_HOST=build.invalid SMTP_USERNAME=build SMTP_PASSWORD=build MAIL_FROM=build@build.invalid \ sh -c '/app/.venv/bin/python manage.py compilemessages && /app/.venv/bin/python manage.py collectstatic --noinput' # Not part of the runtime image: `docker compose --profile test run --rm live-test` FROM builder AS test RUN uv sync --frozen --no-install-project ENV PATH="/app/.venv/bin:$PATH" CMD ["python", "-m", "pytest", "portal/tests/test_directory_live.py", "-v", "-p", "no:cacheprovider"] FROM python:3.13-slim ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 PATH="/app/.venv/bin:$PATH" RUN apt-get update \ && apt-get install -y --no-install-recommends libldap2 libsasl2-2 \ && rm -rf /var/lib/apt/lists/* \ && useradd --system --uid 10001 --no-create-home --shell /usr/sbin/nologin app \ && mkdir /data /backups \ && chown app:app /data /backups WORKDIR /app COPY --from=builder /app /app COPY --chmod=0755 docker ./docker ENV DATA_DIR=/data USER app VOLUME ["/data", "/backups"] EXPOSE 8000 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ CMD ["python", "/app/docker/healthcheck.py"] ENTRYPOINT ["/app/docker/entrypoint.sh"]