# Gondulf IndieAuth Server - OCI-Compliant Containerfile/Dockerfile # Compatible with both Podman and Docker # Optimized for rootless Podman deployment # Build stage - includes test dependencies FROM python:3.12-slim-bookworm AS builder # Install uv package manager (must match version used to create uv.lock) RUN pip install --no-cache-dir uv==0.9.8 # Set working directory WORKDIR /app # Copy dependency files and README (required by hatchling build) COPY pyproject.toml uv.lock README.md ./ # Install all dependencies including test dependencies RUN uv sync --frozen --extra test # Copy source code and tests COPY src/ ./src/ COPY tests/ ./tests/ # Run tests (fail build if tests fail) RUN uv run pytest tests/ --tb=short -v # Production runtime stage FROM python:3.12-slim-bookworm # Copy a marker file from builder to ensure tests ran # This creates a dependency on the builder stage so it cannot be skipped COPY --from=builder /app/pyproject.toml /tmp/build-marker RUN rm /tmp/build-marker # Create non-root user with UID 1000 (compatible with rootless Podman) RUN groupadd -r -g 1000 gondulf && \ useradd -r -u 1000 -g gondulf -m -d /home/gondulf gondulf # Install runtime dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ wget \ sqlite3 \ && rm -rf /var/lib/apt/lists/* # Set working directory WORKDIR /app # Install uv in runtime (needed for running the app) RUN pip install --no-cache-dir uv==0.9.8 # Copy pyproject.toml, lock file, and README (required by hatchling build) COPY pyproject.toml uv.lock README.md ./ # Install production dependencies only (no dev/test) RUN uv sync --frozen --no-dev # Copy application code from builder COPY --chown=gondulf:gondulf src/ ./src/ # Copy entrypoint script COPY --chown=gondulf:gondulf deployment/docker/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh # Create directories for data and backups RUN mkdir -p /data /data/backups && \ chown -R gondulf:gondulf /data # Set environment variables ENV PATH="/app/.venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH=/app/src # Expose port EXPOSE 8000 # Health check using wget HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8000/health || exit 1 # Switch to non-root user USER gondulf # Set entrypoint and default command ENTRYPOINT ["/entrypoint.sh"] CMD ["uvicorn", "gondulf.main:app", "--host", "0.0.0.0", "--port", "8000"]