# ======================================== # Stage 1: Build Documentation from Source (conditional) # ======================================== FROM --platform=$BUILDPLATFORM node:18-alpine AS docs-builder ARG BUILD_DOCS=true # Install git and build dependencies for native modules (like gifsicle) # autoconf, automate, libtool, nasm are needed for building image optimization tools RUN apk add --no-cache \ git \ python3 \ make \ g++ \ autoconf \ automake \ libtool \ nasm WORKDIR /docs-build # Clone the Scribe Security documentation repository only if BUILD_DOCS=true RUN if [ "$BUILD_DOCS" = "true" ] || [ "$BUILD_DOCS" = "1" ]; then \ git clone --depth 1 https://github.com/scribe-security/docs.git .; \ else \ mkdir -p build && echo "Documentation build skipped" > build/index.html; \ fi # Install dependencies and build the documentation only if BUILD_DOCS=true # Set baseUrl to /docs to match our serving path # SKIP_PREFLIGHT_CHECK prevents issues with optional dependencies ENV SKIP_PREFLIGHT_CHECK=true RUN if [ "$BUILD_DOCS" = "true" ] || [ "$BUILD_DOCS" = "1" ]; then \ npm ci && DOCUSAURUS_BASE_URL=/docs npm run build; \ fi # The built static site will be in /docs-build/build # ======================================== # Stage 2: Common Python base on Alpine # ======================================== FROM python:3.11-alpine AS app-base ARG TARGETPLATFORM ARG BUILDPLATFORM ARG TARGETOS ARG TARGETARCH ARG BUILD_DOCS=true ENV PYTHONDONTWRITEBYTECODE=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ PYTHONUNBUFFERED=1 WORKDIR /app # Install runtime deps plus temporary build deps for pip (skip trigger scripts to keep QEMU builds happy) RUN apk add --no-cache --no-scripts --virtual .run-deps \ ca-certificates \ libffi \ openssl \ tini && \ apk add --no-cache --no-scripts --virtual .build-deps \ bash \ build-base \ git \ libffi-dev \ openssl-dev # Keep tooling patched but avoid extra interpreters RUN python -m pip install --upgrade pip && \ python -m venv /opt/venv && \ /opt/venv/bin/pip install --upgrade pip setuptools ENV PATH="/opt/venv/bin:$PATH" # Install Python runtime dependencies COPY pyproject.toml ./ RUN pip install --no-compile -e . # Copy application source COPY . . # App image expects repos to be injected from another stage RUN rm -rf /app/repos && mkdir -p /app/repos # Copy built documentation from build stage COPY --from=docs-builder /docs-build/build /app/static/docs # Remove build deps to keep final layer small (skip triggers for QEMU) RUN apk del --no-scripts .build-deps # ======================================== # Stage 3: Fetch policy repos in a throwaway stage # ======================================== FROM alpine:3.20 AS policy-fetcher WORKDIR /app RUN apk add --no-cache git bash COPY scripts/unpack-git-objects.sh scripts/tag-latest-version.sh ./scripts/ RUN chmod +x ./scripts/unpack-git-objects.sh ./scripts/tag-latest-version.sh RUN mkdir -p /app/repos && \ git clone --bare https://github.com/scribe-public/sample-policies.git /app/repos/sample-policies.git && \ git -C /app/repos/sample-policies.git config uploadpack.allowAnySHA1InWant true && \ git -C /app/repos/sample-policies.git config http.receivepack false && \ git -C /app/repos/sample-policies.git config --local safe.directory '*' RUN /app/scripts/unpack-git-objects.sh && /app/scripts/tag-latest-version.sh # ======================================== # Stage 4: Minimal runtime image (default) # ======================================== FROM app-base AS lean COPY --from=policy-fetcher --chown=1000:1000 /app/repos /app/repos COPY scripts/bootstrap-shell.sh /usr/local/bin/bootstrap-shell RUN chmod +x /usr/local/bin/bootstrap-shell EXPOSE 5003 ENTRYPOINT ["/sbin/tini", "--"] CMD ["gunicorn", "-c", "gunicorn.conf.py", "gunicorn_app:app"] # ======================================== # Stage 5: Debug-friendly runtime image # ======================================== FROM lean AS debug RUN apk add --no-cache --no-scripts \ bash \ bind-tools \ curl \ iproute2 \ iputils \ jq \ less \ lsof \ net-tools \ procps-ng \ strace \ tcpdump \ vim \ wget ENV SHELL=/bin/bash