Files
Knowledge-Base/20 - Knowledge/infrastructure/reverse-proxy-patterns.md

126 lines
3.6 KiB
Markdown

---
title: Reverse Proxy Patterns
description: Common reverse proxy design patterns for self-hosted services and internal platforms
tags:
- reverse-proxy
- networking
- self-hosting
category: infrastructure
created: 2026-03-14
updated: 2026-03-14
---
# Reverse Proxy Patterns
## Introduction
A reverse proxy accepts client requests and forwards them to upstream services. It commonly handles TLS termination, host-based routing, request header forwarding, and policy enforcement in front of self-hosted applications.
## Purpose
Reverse proxies are used to:
- Publish multiple services behind one or a few public entry points
- Centralize TLS certificates
- Apply authentication, authorization, or rate-limiting controls
- Simplify backend service placement and migration
## Architecture Overview
Typical request flow:
```text
Client -> Reverse proxy -> Upstream application
```
Common proxy responsibilities:
- TLS termination and certificate management
- Routing by hostname, path, or protocol
- Forwarding of `Host`, client IP, and other headers
- Optional load balancing across multiple backends
## Common Patterns
### Edge proxy for many internal services
One proxy handles traffic for multiple hostnames:
- `grafana.example.com`
- `gitea.example.com`
- `vault.example.com`
This is a good default for small homelabs and internal platforms.
### Internal proxy behind a VPN
Administrative services are reachable only through a private network such as Tailscale, WireGuard, or a dedicated management VLAN. This reduces public attack surface.
### Path-based routing
Useful when hostnames are limited, but more fragile than host-based routing because some applications assume they live at `/`.
### Dynamic discovery proxy
Tools such as Traefik can watch container metadata and update routes automatically. This reduces manual config for dynamic container environments, but it also makes label hygiene and network policy more important.
## Configuration Example
NGINX example:
```nginx
server {
listen 443 ssl http2;
server_name app.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
}
}
```
Caddy example:
```caddyfile
app.example.com {
reverse_proxy 127.0.0.1:8080
}
```
## Troubleshooting Tips
### Application redirects to the wrong URL
- Check forwarded headers such as `Host` and `X-Forwarded-Proto`
- Verify the application's configured external base URL
- Confirm TLS termination behavior matches application expectations
### WebSocket or streaming traffic fails
- Check proxy support for upgraded connections
- Review buffering behavior if the application expects streaming responses
### Backend works locally but not through the proxy
- Verify the proxy can reach the upstream host and port
- Check the proxy network namespace if running in a container
- Confirm firewall rules permit the proxy-to-upstream path
## Best Practices
- Prefer host-based routing over deep path rewriting
- Publish only the services that need an edge entry point
- Keep proxy configuration under version control
- Use separate internal and public entry points when trust boundaries differ
- Standardize upstream headers and base URL settings across applications
## References
- [NGINX: Reverse Proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
- [Traefik: Routing overview](https://doc.traefik.io/traefik/routing/overview/)
- [Caddy: `reverse_proxy` directive](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy)