Sign inSign up

rackitio/apython_lb

By rackitio

•Updated 3 days ago

async python load balancer / HTTP1,2,3 / Python 3.14.7t / debian trixie slim

Image
Networking
0

555

rackitio/apython_lb repository overview

⁠apython_lb

An async HTTP(S) load balancer and reverse proxy built on Quart⁠. It fronts a pool of backends with round-robin or sticky routing, health checks with a circuit breaker, per-IP rate limiting, a libmodsecurity-powered WAF, URL rewriting, Prometheus metrics, and a live management web UI.

Source & full docs: https://github.com/rackitio/apython_lb⁠

⁠Supported tags

TagDescription
latest, X.Y.Z, X.YBuilt from the corresponding vX.Y.Z release tag in the source repo

Images are multi-arch (linux/amd64, linux/arm64) and rebuilt only on tagged releases — latest always tracks the newest release, never an unreleased commit.

⁠Quick start

The container serves TLS directly and expects /app/cert.pem and /app/key.pem. Generate a self-signed pair for local testing (bring a CA-issued cert/key for anything real):

mkdir -p certs
openssl req -x509 -newkey rsa:2048 -keyout certs/key.pem -out certs/cert.pem \
  -days 365 -nodes -subj "/CN=localhost"

docker run --rm -p 8443:443/tcp -p 8443:443/udp \
  -v "$PWD/certs/cert.pem":/app/cert.pem:ro \
  -v "$PWD/certs/key.pem":/app/key.pem:ro \
  <dockerhub-namespace>/apython_lb:latest

curl -sk https://localhost:8443/health

Then register a backend through the management API:

curl -sk -X POST https://localhost:8443/v1/manage/configs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-backend",
    "proto": "https",
    "host": "example.com",
    "ips": "1.2.3.4,5.6.7.8",
    "hc_path": "/healthz"
  }'

Route a request to it by adding @apython_lb(backend_name="my-backend", ...) to a Quart route — see the source repo for route decorator examples (rate limiting, sticky sessions, URL rewriting).

⁠Ports & volumes

Port443/tcp (HTTP/1.1 and HTTP/2 over TLS) and 443/udp (HTTP/3 over QUIC) — there is no plain-HTTP listener
/app/cert.pem, /app/key.pemTLS certificate and key — required, container will not start without them
/app/dataSQLite database (apython_lb.db) holding backend configs; mount a volume here to persist configs across restarts

⁠Configuration

Set these as container environment variables. Defaults shown are the ones baked into the image.

VariableDefaultDescription
MODSECURITY_ENABLEDtrueWAF on by default; set false to disable
APP_SECRET_KEY(auto-generated)Sticky-session signing key — set explicitly in production, or sessions won't survive restarts/replicas
MANAGE_BASIC_AUTH(unset)user:password for HTTP Basic auth on /v1/manage, /ws/configs, /metrics — on top of the built-in internal-IP restriction
LOG_LEVELINFOINFO = access logs only; DEBUG = all app logs
RATE_LIMIT_REQUESTS / RATE_LIMIT_WINDOW_SECONDS100 / 60App-wide rate limit
HEALTH_CHECK_INTERVAL60Seconds between backend health checks
DNS_NAMESERVERS1.1.1.1Comma-separated resolvers for backend hostname lookups
LB_MAX_ATTEMPTS3Retries per request before giving up

The full variable reference (20+ options covering IP tracking, sticky pinning, TLS verification, and WAF tuning) is in the project README linked above.

⁠Security notes

  • /v1/manage, /ws/configs, and /metrics are restricted to internal (RFC1918/loopback) source IPs by default. If you front this container with another proxy, every client collapses into that proxy's IP — set MANAGE_BASIC_AUTH in that case.
  • Client identity is the TCP peer address; X-Forwarded-For is deliberately not trusted. Run this container as the first hop from clients.
  • The image runs pytest as part of its own build (a dedicated Docker test stage in the source repo) and only publishes if that passes.

⁠Image contents

Base image: debian:trixie-slim with free-threaded CPython 3.14.7 (--disable-gil build, compiled from source — no official Python image ships a free-threaded variant yet), plus libmodsecurity-dev for the WAF engine (loaded via ctypes, no compiler needed at runtime). Served over HTTP/1.1, HTTP/2, and HTTP/3 via Hypercorn. PYTHON_GIL=0 keeps free-threading on even though Hypercorn's HTTP/3 dependency (aioquic) hasn't declared itself GIL-safe — see the source repo's Dockerfile and README for why that's safe here. The test build stage and its dependencies are stripped from the published image — this is a lean production image.

⁠License & issues

See the source repository⁠ for license terms and to file issues or contribute.

Tag summary

Content type

Image

Digest

sha256:31c9f125d…

Size

67.7 MB

Last updated

3 days ago

docker pull rackitio/apython_lb