Docker Awakening Gateway — Roadmap

✅ Completed

Core

  • On-demand container startup — containers sleep until a request arrives, then are started via Docker API
  • Transparent reverse proxy — once running, requests are proxied with zero loading page overhead
  • Concurrency-safe start — per-container mutex prevents duplicate start attempts on concurrent requests
  • WebSocket support — upgrade requests are tunnelled via raw TCP hijack to the backend
  • Host-header routing — O(1) lookup maps Host header → container config; supports N containers on one gateway
  • Query-param fallback?container=NAME for testing without DNS

Configuration & Operations

  • YAML config file (config.yaml) — per-container settings, mounted via volume
  • CONFIG_PATH env override — point to any path for the config file
  • Config validation at startup — gateway fails-fast if config.yaml is missing required fields or contains duplicate definitions
  • Config hot-reloaddocker kill -s HUP docker-gateway reloads config.yaml at runtime without dropping connections
  • Label-based auto-discovery — gateway reads Docker labels (dag.host, dag.target_port, etc.) to automatically discover containers
  • Per-container start_timeout — max time to wait for docker start + TCP probe
  • Per-container idle_timeout — auto-stop containers idle longer than threshold (0 = disabled)
  • Per-container target_port, network, redirect_path
  • Global log_lines — number of container log lines shown in the loading UI
  • Configurable discovery intervalgateway.discovery_interval or DISCOVERY_INTERVAL env var

Reliability

  • TCP readiness probe — after Docker reports “running”, dial ip:port until the app responds
  • HTTP health probe — optionally call a container’s /health endpoint to confirm readiness
  • Early crash detection — if container enters exited/dead during start, fail immediately
  • Start state trackingstarting / running / failed states with error message, exported via /_health
  • Idle watcher goroutine — background loop (every 60s) auto-stops containers exceeding idle_timeout
  • Multi-network support — resolves container IP from a named Docker network; falls back to first available
  • Graceful shutdownSIGTERM/SIGINT triggers http.Server.Shutdown() with grace period

Security

  • Read-only Docker socket — gateway only needs ContainerInspect, ContainerStart, ContainerStop, ContainerLogs
  • Distroless final image (gcr.io/distroless/static) — no shell, no package manager, ~22 MB
  • Rate limiter on internal endpoints — 1 req/s per IP on /_health and /_logs
  • XSS-safe log rendering — log lines injected via textContent, not innerHTML
  • Vendored dependencies — no network access needed during Docker build
  • Admin endpoint authentication — optional basic-auth or bearer token to protect /_status/* and /_metrics
  • CORS / CSRF protection on /_status/wake — prevent cross-origin container start abuse
  • Rate limiter memory cleanup — periodic eviction of stale IPs to prevent unbounded memory growth
  • Trusted proxy configuration — only trust X-Forwarded-For from known upstream proxies

Proxy Headers

  • X-Forwarded-For — appends client IP to the forwarding chain
  • X-Real-IP — original client IP (not overwritten if already set upstream)
  • X-Forwarded-Proto — upstream value preserved; defaults to http
  • X-Forwarded-Host — original Host header value

Frontend (loading page)

  • Animated loading page — dark-themed, breathing container icon, barber-pole progress bar
  • Live log box — polls /_logs every 3s, renders last N lines with auto-scroll
  • Inline error state — on status=failed, swaps progress bar for error box in-place; shows retry button
  • Auto-redirect on ready — polls /_health every 2s; navigates to redirect_path when running

Admin & Observability

  • /_status dashboard — HTML admin page with live status, heartbeat bars, uptime, last request, dark/light mode
  • /_status/api JSON endpoint — snapshot of all containers, polled every 5s
  • /_status/wake action — POST endpoint to trigger container start from dashboard
  • Prometheus /metrics endpoint — per-container counters for requests, starts, durations, idle stops

Groups & Dependencies

  • Container grouping / round-robin routing — start a group of containers, load-balance across replicas
  • Dependency-ordered startupdepends_on triggers topological sort before proxying

Quality

  • Structured logging — Go 1.21+ log/slog JSON-structured output
  • Discovery change detection — only reload when merged config actually differs
  • Unit tests — table-driven tests for config, discovery, rate limiter, proxy routing, security

📅 Medium-term

  • Customisable loading page — per-container colour/logo/message overrides
  • Weighted load balancing — support strategy: weighted with per-container relative weights

🔭 Long-term

  • Multi-instance / distributed state — share startStates and lastSeen via Redis or etcd
  • Built-in TLS termination — ACME/Let’s Encrypt via golang.org/x/crypto/acme/autocert

Known Limitations (by design)

  • Single host only — communicates with the local Docker socket; remote Docker hosts not supported
  • HTTP only — TLS expected to be handled by an upstream proxy (Nginx, Caddy, Traefik)
  • In-memory state — start states and activity timestamps reset on gateway restart

Docker Awakening Gateway — MIT License