Reverse Proxy Setup
NGINX, Caddy, and Traefik configurations
A reverse proxy sits in front of ATStatus, handling SSL termination, caching, and load balancing. This is the recommended setup for production deployments.
Why Use a Reverse Proxy?
Custom Domain
Use status.yourdomain.com instead of IP:port
SSL/HTTPS
Automatic Let's Encrypt certificates
Load Balancing
Distribute traffic across multiple instances
Security Layer
WAF, rate limiting, and DDoS protection
ATStatus Configuration
Before setting up your reverse proxy, configure ATStatus to trust proxy headers:
# .env file
TRUST_PROXY="true"
HOST=0.0.0.0
PORT=3000- TRUST_PROXY="true" - Required for proper header forwarding
- HOST=0.0.0.0 - Listen on all interfaces
- PORT=3000 - Internal port for the proxy to forward to
TRUST_PROXY when running behind a trusted reverse proxy. If your application is directly exposed to the internet, keep it "false".NGINX Proxy Manager
The easiest option with a web-based UI. Perfect for beginners and Docker setups.
Step 1: Add Proxy Host
- Domain: status.yourdomain.com
- Scheme: http
- Forward Hostname: Your server IP or container name
- Forward Port: 3000
Step 2: Enable Features
- Block Common Exploits: ✅ Enabled
- Websockets Support: ✅ Enabled
- Force SSL: ✅ Enabled
- HTTP/2 Support: ✅ Enabled
Step 3: SSL Certificate
Request a new Let's Encrypt certificate in the SSL tab. NGINX Proxy Manager handles renewal automatically.
NGINX (Manual)
server {
listen 80;
server_name status.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name status.example.com;
ssl_certificate /etc/letsencrypt/live/status.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/status.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
}
}Caddy
Caddy is the simplest option - automatic HTTPS with zero configuration.
# Caddyfile
status.example.com {
reverse_proxy localhost:3000
}Traefik
Best for Docker and Kubernetes environments with auto-discovery.
# docker-compose.yml with Traefik labels
services:
atstatus:
image: atstatus
labels:
- "traefik.enable=true"
- "traefik.http.routers.atstatus.rule=Host(`status.example.com`)"
- "traefik.http.routers.atstatus.entrypoints=websecure"
- "traefik.http.routers.atstatus.tls.certresolver=letsencrypt"
- "traefik.http.services.atstatus.loadbalancer.server.port=3000"
networks:
- traefik
traefik:
image: traefik:v2.10
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-certificates:/letsencrypt
networks:
- traefik
volumes:
traefik-certificates:
networks:
traefik:
external: trueCloudflare
Using Cloudflare as a CDN and proxy? Configure these settings:
| Setting | Value | Why |
|---|---|---|
| SSL Mode | Full (Strict) | End-to-end encryption |
| Always Use HTTPS | On | Force secure connections |
| WebSockets | On | For real-time updates |
| Rocket Loader | Off | Can break React apps |
Troubleshooting
WebSocket Connection Fails
Ensure your proxy configuration includes WebSocket support headers (Upgrade and Connection).
Redirect Loops
Set TRUST_PROXY="true" and ensure X-Forwarded-Proto is properly forwarded by your proxy.
Wrong Client IP in Logs
Verify X-Real-IP and X-Forwarded-For headers are set correctly in your proxy configuration.
