A flexible server middleware for any web application. It allows you to serve static files, proxy requests to local websites or Docker containers, and enforce basic authentication with ease. Additionally, it provides structured logs for better observability and troubleshooting.
  • Go 93%
  • Go Template 5.6%
  • JavaScript 1.2%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
maxpeterkaya af7083b936
All checks were successful
CI / build (push) Successful in 4m10s
use /v3
2026-09-25 12:09:17 -04:00
.forgejo/workflows Merge pull request 'chore(deps): update https://vc.maxkaya.com/maxpeterkaya/changelog action to v2' (#68) from renovate/https-vc.maxkaya.com-maxpeterkaya-changelog-2.x into main 2026-09-23 12:59:36 -04:00
auth use /v3 2026-09-25 12:09:17 -04:00
bin fix(js): download from correct repo (oops) 2026-09-02 09:04:57 -04:00
cmd/feeds feat(guard): add build-time feed generator 2026-09-23 00:26:03 -04:00
examples use /v3 2026-09-25 12:09:17 -04:00
guarddata chore(guard): add empty curated UA feed placeholder 2026-09-23 00:25:50 -04:00
views refactor(auth): move forms login template into auth package 2026-09-23 16:54:04 -04:00
.air.toml feat: add air config 2026-09-01 20:21:52 -04:00
.gitignore gitignore tmp folder 2026-09-01 20:24:08 -04:00
.goreleaser.yml rm: remove changelog from goreleaser 2026-07-11 15:53:43 -04:00
.npmignore feat: ignore bin/web-proxy 2025-08-17 23:22:22 -04:00
artifacthub-repo.yml feat: create artifacthub config (#1) 2025-08-08 14:09:39 -04:00
block.go feat(block): match user agent substrings and IP ranges 2026-09-22 20:44:31 -04:00
block_test.go test(block): cover substring matching and CIDR sets 2026-09-22 20:45:01 -04:00
config.go use /v3 2026-09-25 12:09:17 -04:00
config_test.go test(config): cover rooted path filtering 2026-09-23 16:50:11 -04:00
Dockerfile chore(deps): update debian docker tag to v13 2026-01-26 01:00:11 +00:00
Dockerfile-snapshot chore(deps): update golang docker tag to v1.27 2026-08-19 20:28:37 +00:00
functions.go feat: add health balancer to round robin 2026-08-17 11:24:41 -04:00
go.mod mod /v3 2026-09-25 11:59:52 -04:00
go.sum build: refresh checksums after module path change 2026-09-23 16:42:52 -04:00
guard.go use /v3 2026-09-25 12:09:17 -04:00
guard_challenge.go use /v3 2026-09-25 12:09:17 -04:00
guard_challenge_test.go use /v3 2026-09-25 12:09:17 -04:00
guard_feeds.go feat(guard): load embedded feeds with fast IP and UA matching 2026-09-23 00:26:33 -04:00
guard_goodbots.go feat(guard): verify good crawlers by reverse DNS 2026-09-23 00:26:40 -04:00
guard_test.go use /v3 2026-09-25 12:09:17 -04:00
healthcheck.go feat(healthcheck): send outbound API key on HTTP probes 2026-09-15 20:48:24 -04:00
healthcheck_test.go test(healthcheck): cover HTTP path probe 2026-09-13 17:58:34 -04:00
INSTALL-GUIDE.md docs: update install guide 2026-09-02 09:03:24 -04:00
LICENSE Initial commit 2025-08-08 13:48:48 -04:00
main.go use /v3 2026-09-25 12:09:17 -04:00
package-lock.json Release NPM 1.0.5 2026-09-02 09:05:10 -04:00
package.json Release NPM 1.0.5 2026-09-02 09:05:10 -04:00
README.md docs: link standalone auth middleware and library example 2026-09-23 16:54:32 -04:00
renovate.json Add renovate.json 2026-01-26 00:08:16 +00:00
transport.go use /v3 2026-09-25 12:09:17 -04:00
transport_test.go use /v3 2026-09-25 12:09:17 -04:00
USAGE-GUIDE.md docs(guard): document bot guard configuration 2026-09-23 00:29:57 -04:00

web-proxy

Artifact Hub image image image image

web-proxy is a reverse proxy that gives production grade structured logs to web applications that were not built with observability in mind. Many popular frameworks log inconsistently, and some production builds drop logging entirely. NextJS and Prisma ORM are typical examples. Instead of editing application code, run web-proxy in front of the application. Every request is logged as structured JSON before it is forwarded upstream, so traffic becomes queryable in Grafana, Loki, and Promtail.

What a request looks like

When a client hits the proxy, web-proxy records the full picture of the exchange.

{
  "level": "info",
  "status": 200,
  "method": "GET",
  "URI": "/api/items?page=2",
  "route": "/api/items",
  "protocol": "HTTP/1.1",
  "remote_ip": "203.0.113.8",
  "host": "example.com",
  "referer": "https://example.com/home",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
  "id": "6f9c2ab7e4d84a2f",
  "latency": 2850000,
  "latency_human": "2.85ms",
  "bytes_in": 0,
  "bytes_out": 4182,
  "target": "http://localhost:3001"
}

Every log line carries the request ID, the client IP taken from the X-Forwarded-For header, the proxy target that served the request, and latency in nanoseconds plus a human readable form. Requests whose paths carry a file extension are logged separately from application routes, which keeps static asset noise easy to filter. Failed requests produce an error level line with the same fields plus the underlying error.

Features

  • Structured JSON logs for every request with status, method, path, latency, bytes transferred, request ID, and real client IP.
  • Reverse proxying to a single application or load balancing across several upstreams.
  • TCP or HTTP health checks that drop dead upstreams from rotation and answer 503 when every target is down.
  • Static hosting for frontend builds.
  • Managed mode that starts your web application and forwards public traffic to it.
  • Access control through basic auth, bearer keys, a branded session login page, OpenID Connect, or any combination of these at once, also importable as a standalone auth middleware for any Go service.
  • Blocking by user agent substring or client IP and CIDR range.
  • A built-in bot guard: severity tiers that score requests from curated IP/UA feeds, honeypots, header sanity, and per-IP behaviour, then block, throttle, tarpit, or serve a JS or proof-of-work challenge.
  • Configuration through environment variables with safe defaults and .env support.

Quick start

npm

web-proxy ships as an npm package that downloads the matching binary during installation.

npm i @maxpeterkaya/web-proxy

Add the scripts below to package.json to let web-proxy run your application.

{
  "scripts": {
    "start:web": "next start",
    "start": "npx web-proxy -app"
  }
}

Start it with npm run start. web-proxy reads the start:web script, launches your app on an internal port, and serves it on PORT 3000 by default. Detailed setup and the concurrent alternative live in the Install Guide.

Docker

The container image vc.maxkaya.com/maxpeterkaya/web-proxy:latest runs web-proxy on its own. Wire it into a compose stack to log a sibling service.

services:
  proxy:
    image: vc.maxkaya.com/maxpeterkaya/web-proxy:latest
    ports:
      - "3000:3000"
    environment:
      PROXY_TARGETS: app:3001

  app:
    image: your-app:latest
    expose:
      - "3001"

Replace your-app with your own image and match the service name and port to your stack.

Binary

Release binaries are published for Linux, macOS, FreeBSD, OpenBSD, and NetBSD across amd64, arm, and arm64. The Install Guide covers every way to obtain web-proxy.

Run modes

Mode Invocation What it does
Managed app web-proxy -app Starts your application from package.json and proxies public traffic to it
Reverse proxy web-proxy Forwards PORT to an upstream application on PROXY_PORT
Load balancer web-proxy with PROXY_TARGETS set Distributes requests across upstreams that pass health checks
Static site web-proxy -static Serves the frontend build in -static-dir

Container deployments can wrap an existing image as middleware inside the application container or as a separate proxy container. See the container middleware and container proxy examples for those setups.

Configuration

web-proxy is configured through environment variables and honors a .env file in the working directory. Every variable has a default, so the proxy runs without any setup. The Usage Guide contains the complete variable reference.

Examples

Roadmap

These items are in no particular order.

  • Screenshots
  • Benchmarks
  • Configurable logs
  • Templates

License

web-proxy is released under the Apache License 2.0.