A lightweight HTTP reverse proxy sidecar that rewrites paths and query parameters based on a YAML configuration. Designed to run as a Kubernetes sidecar container alongside your main application.
http-rewrite listens for incoming HTTP requests and proxies them to a backend service, rewriting URL paths and/or query parameters on the fly. Route patterns support named captures and wildcards, and captured values can be interpolated into the target path or query using ${variable} syntax.
Use cases include:
- Extracting path segments (e.g. language codes) and mapping them to query parameters
- Normalizing URL structures between an API gateway and a backend service
- Returning static HTTP responses for unmatched routes (e.g.
402 Payment Required)
- Go 1.23+
- Docker (for container builds)
go run . -c examples/echo.yaml# Build the image
docker build . -t rewrite
# Run with a config file
docker run -it --rm \
--mount type=bind,source=$(pwd)/examples/echo.yaml,target=/config.yaml \
-p 0.0.0.0:8081:8081 \
rewriteOr use the published image directly:
docker run -it --rm \
--mount type=bind,source=$(pwd)/examples/echo.yaml,target=/config.yaml \
-p 0.0.0.0:8081:8081 \
lindex/http-rewrite:v0.3.1The proxy is configured via a YAML file (default: config.yaml, override with -c <path>).
listen: 8081 # Port to listen on
apis: # List of routing rules (evaluated in order)
- input: ...
proxy: ... # OR http: ...| Field | Type | Description |
|---|---|---|
path |
string | chi-compatible route pattern (supports {param} and {*} wildcards) |
method |
string | Single HTTP method, or ALL / * for any |
methods |
list of strings | Multiple HTTP methods (mutually exclusive with method) |
| Field | Type | Description |
|---|---|---|
scheme |
string | http (default) or https |
host |
string | Target hostname (default: localhost) |
port |
int | Target port (required) |
path |
string | Rewritten path, supports ${param} and ${*} interpolation |
query |
object | Query parameter overrides (see below) |
query.set — map of query parameter names to values (supports ${param} interpolation):
query:
set:
lang: "${lang}"| Field | Type | Description |
|---|---|---|
status |
int | HTTP status code |
body |
string | Optional response body |
Captured route parameters are available as ${param}. The wildcard tail segment is available as ${*}.
Environment variables are also substituted using the same ${VAR} syntax (via ninlil/envsubst).
Routes GET /sv/some/path?arg1=1 → GET localhost:10000/some/path?arg1=1&lang=sv
Unmatched routes return 402 Unknown.
listen: 8081
apis:
- input:
methods:
- GET
- PUT
path: /{lang:[a-z]{2}}/*
proxy:
scheme: http
host: localhost
port: 10000
path: /${*}
query:
set:
lang: "${lang}"
- input:
method: ALL
path: /*
http:
status: 402
body: "Unknown"Same as above but proxies unmatched routes through instead of returning an error.
listen: 8081
apis:
- input:
methods:
- GET
- PUT
path: /{lang:[a-z]{2}}/*
proxy:
scheme: http
host: localhost
port: 10000
path: /${*}
query:
set:
lang: "${lang}"
- input:
method: ALL
path: /*
proxy:
scheme: http
host: localhost
port: 10000
path: /${*}http-rewrite is designed to run as a sidecar container. The main application container does not expose its port directly — all traffic is routed through the rewrite sidecar.
Store the configuration in a ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-rewrite-config
data:
config.yaml: |-
listen: 8081
apis:
- input:
methods: [GET, PUT]
path: /{lang:[a-z]{2}}/*
proxy:
host: localhost
port: 10000
path: /${*}
query:
set:
lang: "${lang}"
- input:
method: ALL
path: /*
proxy:
host: localhost
port: 10000
path: /${*}apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: main
image: lindex/http-https-echo:v0.1.0
# Port NOT exposed — rewrite sidecar handles inbound traffic
- name: rewrite-sidecar
image: lindex/http-rewrite:v0.3.1
ports:
- containerPort: 8081
volumeMounts:
- name: rewrite-config
mountPath: /config.yaml
subPath: config.yaml
volumes:
- name: rewrite-config
configMap:
name: myapp-rewrite-configapiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- name: http
port: 80
targetPort: 8081Images are published to Docker Hub as lindex/http-rewrite.
| Tag pattern | Description |
|---|---|
v1.2.3 |
Exact version |
v1.2 |
Latest patch for a minor version |
The image is built on gcr.io/distroless/static-debian12 and runs as a non-root user.
# Run tests
go test ./...
# Build binary
go build -o http-rewrite .
# Build Docker image
docker build . -t rewrite