Docker Deployment

Container deployment with Docker and Docker Compose

Docker Image

The official Docker image is available from GitHub Container Registry:

docker pull soapbucket/sbproxy:latest

Or build from source:

docker build -t sbproxy .

Quick Start

Run SBproxy with a local config file:

docker run -d \
  -p 8080:8080 \
  -p 8443:8443 \
  -v ./sb.yml:/etc/sbproxy/sb.yml:ro \
  soapbucket/sbproxy:latest

Docker Compose

The repository includes a full Docker Compose stack with SBproxy, Redis, Prometheus, Grafana, Jaeger, and a Pebble ACME test server. Clone the repo and start the stack:

git clone https://github.com/soapbucket/sbproxy.git
cd sbproxy
docker compose -f docker/docker-compose.yml up --build

What's in the Stack

ServicePortPurpose
sbproxy8080, 8443Proxy (HTTP + HTTPS)
redis6379Distributed rate limiting and pub/sub config reload
pebble14000, 15000ACME test server for auto-TLS certificates
prometheus9090Metrics scraping (every 15s)
grafana3000Dashboards (no login required)
jaeger16686Distributed tracing UI

Compose File

services:
  sbproxy:
    build:
      context: ..
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
      - "8443:8443"
      - "8443:8443/udp"
    volumes:
      - ./sb.yml:/etc/sbproxy/sb.yml:ro
    environment:
      - SB_LOG_LEVEL=info
    depends_on:
      redis:
        condition: service_healthy
    networks:
      - sbnet

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
    networks:
      - sbnet

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    networks:
      - sbnet

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    volumes:
      - ./grafana/datasources.yml:/etc/grafana/provisioning/datasources/datasources.yml:ro
    depends_on:
      - prometheus
    networks:
      - sbnet

  jaeger:
    image: jaegertracing/all-in-one:latest
    ports:
      - "16686:16686"
      - "4317:4317"
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    networks:
      - sbnet

networks:
  sbnet:
    driver: bridge

SBproxy Config for Docker Compose

The included docker/sb.yml configures tracing and Redis-backed rate limiting. Prometheus metrics are served from /metrics on the main HTTP port (no separate listener):

proxy:
  http_bind_port: 8080
  https_bind_port: 8443

otel:
  enabled: true
  otlp_endpoint: jaeger:4317
  otlp_protocol: grpc
  otlp_insecure: true
  service_name: sbproxy
  sample_rate: 1.0

l2_cache_settings:
  driver: redis
  params:
    dsn: redis://redis:6379/0

origins:
  "demo.localhost":
    action:
      type: proxy
      url: https://httpbin.org
    policies:
      - type: rate_limit
        limit: 10
        window: 1m
        key: client_ip

Testing the Stack

Generate traffic to populate metrics and traces:

for i in $(seq 1 20); do
  curl -s -o /dev/null -w "%{http_code}\n" \
    -H "Host: demo.localhost" http://localhost:8080/get
  sleep 0.5
done

Then open:

  • Grafana: http://localhost:3000 - query sbproxy_requests_total
  • Jaeger: http://localhost:16686 - select "sbproxy" from the Service dropdown
  • Prometheus: http://localhost:9090 - try rate(sbproxy_requests_total[1m])

Customizing

Edit docker/sb.yml and restart:

docker compose -f docker/docker-compose.yml restart sbproxy

Or send a reload signal for zero-downtime config updates:

docker compose -f docker/docker-compose.yml kill -s HUP sbproxy