Have you ever wanted to build your own reverse proxy from scratch, with all the flexibility of dynamic configuration, hot reload, and load balancing—without relying on Nginx or Traefik?
In this project, I built a fully working reverse proxy server in Go, supporting features like YAML-based configuration, basic authentication, path rewriting, round-robin routing, and live configuration reloads. It’s also fully containerized with Docker and tested using GitHub Actions.
Let me walk you through the highlights of this project and why it’s more than just a toy proxy.
What Is a Reverse Proxy?
A reverse proxy is a server that sits between clients and backend services, forwarding client requests to the appropriate internal services. It's used for load balancing, authentication, caching, rewriting URLs, and more. Think of it as your system’s traffic controller.
Why I Built My Own
Tools like Nginx and Caddy are excellent—but sometimes too abstract. I wanted to understand how things work under the hood: how a proxy handles routes, manages load balancing, or reloads configs without restarting. By building my own, I learned deeply about Go’s net/http, reverse proxying via httputil, and how to structure production-ready systems.
Features
This proxy isn’t just functional—it’s production-aware. Here’s what it includes:
Dynamic YAML configuration
Round-robin load balancing between multiple targets
Health checks via /health endpoints
Path rewriting (e.g., /api -> /user)
Basic Authentication for protected routes
Hot reload on config file changes (no need to restart the server)
Logging and rate limiting middleware
Unit tested with Go's testing package
CI pipeline using GitHub Actions for test + Docker build
**Project Structure
**Here’s how the project is organized:
main.go: Entry point with middleware setup and hot reload logic
router.go: Core reverse proxy logic, request handling, round-robin logic
router_test.go: Unit tests for health checks, load balancing, and rewrite logic
routes.yaml: Defines dynamic routing rules, targets, auth credentials
api-backend/: Sample API service for testing (written in Go, Dockerized)
.github/workflows/ci.yml: GitHub Actions config for CI pipeline
**Example Configuration (routes.yaml)
**The YAML file defines how incoming paths are routed to target servers, including optional authentication and rewrite paths. For example:
yaml
Kopyala
Düzenle
routes:
- path: /api
targets:
- http://localhost:5001
- http://localhost:5003 auth: username: admin password: 1234 rewrite: /user This means any request to /api will be routed in round-robin fashion to the targets, protected with basic auth, and the path will be rewritten to /user.
**Hot Reload in Action
**One of the biggest challenges was implementing a hot reload system that watches the config file for changes. If routes.yaml is updated, the server reloads routes without restarting. This mimics how systems like Traefik work and adds flexibility in dynamic environments.
**CI/CD Setup
**Every commit triggers the following steps via GitHub Actions:
Runs all Go unit tests
Builds the Docker image for the API backend
(Optional) Could be extended to push to Docker Hub or deploy to a staging environment
This ensures the proxy remains stable and buildable at all times.
**Lessons Learned
**Go’s net/http and httputil.ReverseProxy provide great building blocks for low-level HTTP control.
YAML makes dynamic configuration super clean for routing rules.
Hot reload can be implemented simply with file watchers and mutex locking.
Writing tests for a proxy server can be tricky, especially when simulating backend servers, but it's possible with httptest.
**What’s Next?
**Adding a Web UI dashboard to visualize logs, active routes, and traffic
Support for JWT authentication
Metrics support with Prometheus
Redis-backed caching layer
Live reload via SIGHUP signal or WebSocket interface
Conclusion
This project was both a systems exercise and a backend engineering challenge. If you're learning Go or preparing for DevOps roles, building something like this sharpens your skills in concurrency, testing, and real-world infrastructure patterns.
You can find the full code here:
GitHub Repo: github.com/yusufbender/bender-reverse-proxy
If you like the project, feel free to star it or fork and extend it!
Let me know what you think—or even better, contribute and build together 🚀
Top comments (0)