The health check endpoint now properly indicates service unavailability: - Returns HTTP 200 when fail2ban is online - Returns HTTP 503 when fail2ban is offline This allows Docker and other orchestration tools to correctly detect when fail2ban is unreachable and automatically restart the backend container, preventing the situation where Docker treats the container as healthy despite fail2ban being down. Changes: - Update GET /api/health to return 503 on fail2ban offline - Return appropriate JSON response bodies for each state - Update tests to verify both online (200) and offline (503) scenarios - Update Dockerfile HEALTHCHECK documentation - Add Health Checks section to Deployment.md documentation All tests pass with 100% coverage on health.py. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
88 lines
3.4 KiB
Docker
88 lines
3.4 KiB
Docker
# ──────────────────────────────────────────────────────────────
|
|
# BanGUI — Backend image (Python / FastAPI)
|
|
#
|
|
# Compatible with Docker and Podman.
|
|
# Build context must be the project root.
|
|
#
|
|
# Usage:
|
|
# docker build -t bangui-backend -f Docker/Dockerfile.backend .
|
|
# podman build -t bangui-backend -f Docker/Dockerfile.backend .
|
|
# ──────────────────────────────────────────────────────────────
|
|
|
|
# ── Stage 1: build dependencies ──────────────────────────────
|
|
FROM docker.io/library/python:3.12-slim AS builder
|
|
|
|
WORKDIR /build
|
|
|
|
# Install build-time system dependencies
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends gcc libffi-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
COPY backend/pyproject.toml /build/
|
|
|
|
# Install Python dependencies into a virtual-env so we can copy it cleanly
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
RUN pip install --no-cache-dir --upgrade pip \
|
|
&& pip install --no-cache-dir .
|
|
|
|
# ── Stage 2: runtime image ───────────────────────────────────
|
|
FROM docker.io/library/python:3.12-slim AS runtime
|
|
|
|
LABEL maintainer="BanGUI" \
|
|
description="BanGUI backend — fail2ban web management API"
|
|
|
|
# Non-root user for security
|
|
RUN groupadd --gid 1000 bangui \
|
|
&& useradd --uid 1000 --gid bangui --shell /bin/bash --create-home bangui
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy the pre-built virtual-env
|
|
COPY --from=builder /opt/venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH" \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1
|
|
|
|
# Copy application source
|
|
COPY backend/app /app/app
|
|
COPY fail2ban-master /app/fail2ban-master
|
|
|
|
# Data directory for the SQLite database
|
|
RUN mkdir -p /data && chown bangui:bangui /data
|
|
VOLUME ["/data"]
|
|
|
|
# Default environment values (override at runtime)
|
|
ENV BANGUI_DATABASE_PATH="/data/bangui.db" \
|
|
BANGUI_FAIL2BAN_SOCKET="/var/run/fail2ban/fail2ban.sock" \
|
|
BANGUI_LOG_LEVEL="info" \
|
|
BANGUI_WORKERS="1"
|
|
|
|
EXPOSE 8000
|
|
|
|
USER bangui
|
|
|
|
# Health-check using the built-in health endpoint
|
|
# Returns exit 0 (success) for HTTP 200 (fail2ban online)
|
|
# Returns exit 1 (failure) for HTTP 503 (fail2ban offline)
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health'); print('healthy')" || exit 1
|
|
|
|
# ⚠️ IMPORTANT: Single-Worker Requirement
|
|
# BanGUI must always run as a single worker process:
|
|
# - Do NOT pass --workers or --worker-class to uvicorn
|
|
# - Do NOT use gunicorn with -w 4 or similar
|
|
# - Do NOT override BANGUI_WORKERS to > 1
|
|
#
|
|
# Why? The session cache is process-local. Multiple workers would cause:
|
|
# - Random user logouts (sessions not shared between workers)
|
|
# - Duplicate background jobs (each worker runs the scheduler)
|
|
# - SQLite lock contention and timeouts
|
|
#
|
|
# For high availability, use container orchestration (Kubernetes, Docker Swarm)
|
|
# to run multiple instances, not multiple workers in a single process.
|
|
#
|
|
# See Docs/Architekture.md § Deployment Constraints for details.
|
|
CMD ["uvicorn", "app.main:create_app", "--factory", "--host", "0.0.0.0", "--port", "8000"]
|