This project implements a high-performance reverse proxy built with Pingora - Cloudflare's Rust framework for building fast, reliable network services. The proxy comes with integrated Docker Swarm service discovery, automatic TLS certificate management via Let's Encrypt, and a flexible management API.
- HTTP/HTTPS Proxying: Route traffic to backend services based on hostname
- Dynamic Configuration: Update routing rules without restarting the proxy
- Automatic TLS: Integration with Let's Encrypt for automatic certificate issuance
- Docker Swarm Integration: Automatic service discovery for Docker Swarm deployments
- Management API: HTTP/HTTPS endpoints for configuration management
# Start the proxy with Docker Compose
docker-compose up -d
The proxy is configured through a JSON file (config.json
) that maps domains to backend services:
{
"servers": [
{
"from": "example.com",
"to": "192.168.1.100:8080"
},
{
"from": "api.example.com",
"to": "192.168.1.101:3000"
}
]
}
When running in Docker Swarm mode, the proxy automatically discovers services with the com.koompi.proxy=true
label.
docker service create \
--name my-web-app \
--network ingress \
--label com.koompi.proxy=true \
--label com.koompi.proxy.domain=app.example.com \
--label com.koompi.proxy.port=3000 \
nginx:latest
The proxy integrates with Let's Encrypt to automatically obtain and renew TLS certificates for your domains. Certificates are stored in the certbot/letsencrypt/live/{domain}
directory.
The management API is available on port 81 (HTTP) and port 8443 (HTTPS if certificates are available).
Endpoint | Method | Description |
---|---|---|
GET / |
GET | List all domain mappings |
PUT /{domain}/{backend} |
PUT | Update an existing mapping |
POST /{domain}/{backend} |
POST | Add a new mapping |
DELETE /{domain} |
DELETE | Remove a mapping |
curl -X POST "http://localhost:81/example.com/192.168.1.100:8080"
Endpoint | Method | Description |
---|---|---|
POST /certificates |
POST | Request a new certificate |
GET /certificates/{domain} |
GET | Check certificate status |
curl -X POST "http://localhost:81/certificates" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","email":"[email protected]"}'
curl "http://localhost:81/certificates/example.com"
The proxy includes automatic service discovery for Docker Swarm deployments. It looks for services with specific labels:
com.koompi.proxy=true
- Marks the service for discoverycom.koompi.proxy.domain
- The domain to route traffic to this servicecom.koompi.proxy.port
- The port the service listens on (defaults to 80)com.koompi.org.id
- Optional organization ID for network isolation
version: '3.7'
services:
web:
image: nginx
deploy:
labels:
com.koompi.proxy: "true"
com.koompi.proxy.domain: "example.com"
com.koompi.proxy.port: "80"
The proxy consists of three main services:
- HTTP Proxy: Handles HTTP traffic and Let's Encrypt challenges
- HTTPS Proxy: Handles HTTPS traffic with TLS termination
- Manager Proxy: Provides the configuration API
Additionally, a Swarm Discovery Service runs in the background when in Swarm mode to automatically detect services.
For multi-tenant deployments, the proxy can extract organization information from the domain and forward it as a header:
# Input format
org_id.service_name.network:port
# Results in adding header
X-Organization-ID: org_id
TLS settings are configured using Pingora's TlsSettings::intermediate
profile, which provides a good balance of security and compatibility.
- Certificate not found: Check the
certbot/letsencrypt/live
directory for your domain - Service not discovered: Ensure services have the correct labels
- HTTP Challenge failing: Make sure port 80 is accessible from the internet
The proxy outputs detailed logs that can help diagnose issues:
# View logs
docker-compose logs -f
- Rust 1.65 or later
- Docker 20.10 or later (for Swarm mode)
# Clone the repository
git clone https://github.com/koompi/pingora-proxy-server.git
cd pingora-proxy-server
# Build the project
cargo build --release
# Run with custom configuration
RUST_LOG=info ./target/release/pingora-proxy-server
Variable | Description | Default |
---|---|---|
DOCKER_ENDPOINT |
Docker API endpoint | unix:///var/run/docker.sock |
SWARM_MODE |
Enable Docker Swarm discovery | false |
SWARM_NETWORKS |
Networks to check for services | ingress |
LOG_LEVEL |
Logging verbosity | info |
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Cloudflare Pingora - The high-performance Rust proxy framework
- certbot - For Let's Encrypt integration
- bollard - Rust Docker API client