A dynamic, regex-based reverse proxy for Kubernetes development environments. Written in Go, backed by SQLite (WAL mode), with a dual-port architecture:
- :8080 — Data plane (proxies traffic to backends)
- :9090 — Admin API (manage routes dynamically)
| Tool | Min Version | Install |
|---|---|---|
| Go | 1.22 | https://go.dev/dl |
| gcc | any | apt install gcc / brew install gcc |
| make | any | usually pre-installed |
| curl + jq | any | apt install curl jq / brew install curl jq |
| Docker | 20+ | https://docs.docker.com/get-docker (optional) |
Why gcc? The
go-sqlite3driver wraps the C SQLite amalgamation via CGO. CGO_ENABLED=1 and a C compiler are required at build time.
# 1. Unzip the project
Clone the project
cd proxy-router
# 2. Download Go dependencies
go mod download
# 3. Run the ALB (creates .data/alb.db automatically)
make runYou should see output like:
{"level":"info","msg":"starting ALB","listen":":8080","admin":":9090","db":".data/alb.db"}
{"level":"info","msg":"routing engine initialised","routes_loaded":0}
{"level":"info","msg":"data plane listening","addr":":8080"}
{"level":"info","msg":"admin plane listening","addr":":9090"}
go version # must be go1.22+
gcc --version # any version
make --version
curl --versiongo mod download
go mod tidyThe ALB stores its SQLite DB here. Override with ALB_DB_PATH env var if needed.
mkdir -p .dataALB_LISTEN_ADDR=:8080 \
ALB_ADMIN_ADDR=:9090 \
ALB_DB_PATH=.data/alb.db \
go run ./cmd/albOr simply:
make runmake build
# Binary placed at ./bin/alb
make run-bin # build + run the compiled binaryOpen a second terminal and run these commands while the ALB is running.
curl http://localhost:9090/healthz
# {"status":"ok"}Routes are regex patterns mapped to backend URLs.
# Route /api/users/* → a local backend
curl -X POST http://localhost:9090/routes \
-H "Content-Type: application/json" \
-d '{
"sandbox_id": "sandbox-1",
"pattern": "^/api/users(/.*)?$",
"target_url": "http://httpbin.org",
"priority": 10
}'
curl -X POST http://localhost:9090/routes \
-H "Content-Type: application/json" \
-d '{
"sandbox_id": "sandbox-tmp2",
"pattern": "^/websdk/k8s-app-v3/.*",
"target_url": "http://dev-eks-svc-websdk.hs-pre-issueflow.svc.cluster.local:9017",
"priority": 1
}'
# {"id":1}BASE=https://api-router.sbox.dev.helpshift.com/websdk/k8s-app-v3/test
curl http://localhost:9090/routes | jq .# Should proxy to httpbin.org/get and return 200
curl -v http://localhost:8080/api/users/get
# Check for ALB response headers:
# X-ALB-Sandbox: sandbox-1
# X-ALB-Route-ID: 1curl -v http://localhost:8080/no-such-path
# HTTP/1.1 404 Not Found
# {"error":"no route matched","path":"/no-such-path"}# Add a route pointing to a dead service
curl -X POST http://localhost:9090/routes \
-H "Content-Type: application/json" \
-d '{
"sandbox_id": "sandbox-bad",
"pattern": "^/dead(/.*)?$",
"target_url": "http://localhost:19999",
"priority": 10
}'
curl -v http://localhost:8080/dead/anything
# HTTP/1.1 502 Bad Gateway
# {"error":"bad gateway","target":"localhost:19999","detail":"..."}curl -X DELETE http://localhost:9090/routes/1
# {"status":"deleted"}curl -X DELETE http://localhost:9090/sandboxes/sandbox-1
# {"deleted":2,"sandbox_id":"sandbox-1"}curl -X POST http://localhost:9090/routes/reload
# {"status":"reloaded"}Requires the ALB to be running in another terminal.
make smoke-testmake docker-buildmake docker-run
# Binds :8080 and :9090, mounts .data/ as /data inside containermkdir -p .data
docker run --rm \
-p 8080:8080 \
-p 9090:9090 \
-v $(pwd)/.data:/data \
-e ALB_DB_PATH=/data/alb.db \
alb:local- A running cluster (
kubectl cluster-infoshould work) kubectlconfigured with appropriate permissions- A container registry to push the image
# 1. Build and push the image
docker build -t yourrepo/alb:latest .
docker push yourrepo/alb:latest
# 2. Update the image name in k8s/deployment.yaml
sed -i 's|yourrepo/alb:latest|<YOUR_REGISTRY>/alb:latest|g' k8s/deployment.yaml
# 3. Apply RBAC
kubectl apply -f k8s/rbac.yaml
# 4. Deploy (creates namespace, PVC, Deployment, Services)
kubectl apply -f k8s/deployment.yaml
# 5. Wait for rollout
kubectl rollout status deployment/alb -n sandbox-alb-system
# 6. Access the admin API via port-forward
kubectl port-forward svc/alb-admin 9090:9090 -n sandbox-alb-system &
# 7. Access the data plane via port-forward
kubectl port-forward svc/alb 8080:80 -n sandbox-alb-system &
# 8. Health check
curl http://localhost:9090/healthz| Variable | Default | Description |
|---|---|---|
ALB_LISTEN_ADDR |
:8080 |
Data plane bind address |
ALB_ADMIN_ADDR |
:9090 |
Admin API bind address |
ALB_DB_PATH |
/data/alb.db |
Path to SQLite database file |
ALB_DIAL_TIMEOUT_SEC |
5 |
TCP dial timeout to backends (seconds) |
ALB_RESPONSE_TIMEOUT_SEC |
30 |
Full response timeout (seconds) |
| Method | Path | Description |
|---|---|---|
| GET | /healthz |
Liveness check |
| GET | /routes |
List all active routes |
| POST | /routes |
Add a new route |
| DELETE | /routes/{id} |
Delete route by ID |
| POST | /routes/reload |
Reload all routes from DB |
| DELETE | /sandboxes/{id} |
Delete all routes for a sandbox |
{
"sandbox_id": "sandbox-1",
"pattern": "^/api/v1/users(/.*)?$",
"target_url": "http://user-service.sandbox-1.svc.cluster.local:8080",
"priority": 10
}priority: lower number = evaluated first. Defaults to100.pattern: valid Goregexpsyntax (RE2).
cgo: C compiler "gcc" not found
→ Install gcc: sudo apt install gcc (Linux) or xcode-select --install (macOS)
cannot find package "github.com/mattn/go-sqlite3"
→ Run go mod download first
bind: address already in use
→ Change ports: ALB_LISTEN_ADDR=:18080 ALB_ADMIN_ADDR=:19090 make run
SQLite "database is locked" → Only one process should write to the DB. Stop any other ALB instance first.
Docker build fails on arm64 (Apple Silicon)
→ Add --platform linux/amd64 or change GOARCH to arm64 in the Dockerfile.