CHOMPER WIKI

No results for “”

Self-hosting behind your own reverse proxy or CDN

Self-hosting behind your own reverse proxy or CDN

Chomper's containers (chomper-ui, chomper-ingestion, and any paid module such as Network Probes) are commonly placed behind a reverse proxy you already run (nginx, Apache) and/or a CDN/WAF in front of that, such as Cloudflare. This page covers the two configuration points customers hit most often, plus two smaller gotchas worth knowing up front.

1. Keep a persistent, keepalive connection to chomper-ui

A bare proxy_pass with no upstream keepalive and no explicit timeouts works most of the time, but a single transient connection hiccup between your reverse proxy and chomper-ui can surface as a one-shot 502 — which your CDN then renders as its own branded error page, making it look worse than it is. The fix is a persistent upstream block with keepalive and explicit timeouts.

nginx

upstream chomper_ui {    server 10.0.0.5:3001;    keepalive 32;} server {    listen 443 ssl;    server_name dashboard.example.com;     location / {        proxy_pass http://chomper_ui;        proxy_http_version 1.1;        proxy_set_header Connection "";        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_connect_timeout 5s;        proxy_send_timeout 30s;        proxy_read_timeout 30s;    }}

The Connection "" header is what actually enables keepalive reuse on the upstream hop — without it, nginx forwards the client's own Connection: close, and every request pays a fresh TCP+TLS handshake to chomper_ui regardless of the keepalive directive above it.

Apache (mod_proxy)

Requires proxy and proxy_http enabled (a2enmod proxy proxy_http):

<VirtualHost *:443>    ServerName dashboard.example.com     ProxyPreserveHost On    ProxyTimeout 30     <Location "/">        ProxyPass "http://10.0.0.5:3001/" keepalive=On connectiontimeout=5 timeout=30        ProxyPassReverse "http://10.0.0.5:3001/"    </Location></VirtualHost>

2. Modules with an external agent need their own carve-out

The Network Probes module's agents (the small process you install on remote hosts to run ping/DNS/curl/traceroute checks) reach chomper-ui through a dedicated public route, /agent-proxy/network-probes/agent/*. It's intentionally public at the chomper-ui level — the module's own issued key authenticates each request, not your reverse proxy or your IP allowlist.

If your dashboard vhost is IP-restricted — a common pattern when only office/VPN IPs should reach the UI — that restriction applies to every path on the vhost unless you explicitly carve the agent path out. An agent host is essentially never one of your allowlisted IPs, since it runs wherever you're actually monitoring from.

nginx

server {    listen 443 ssl;    server_name dashboard.example.com;     # Public — no allow/deny here. Auth is the module's own key, not the caller IP.    location /agent-proxy/network-probes/agent/ {        proxy_pass http://chomper_ui;        proxy_http_version 1.1;        proxy_set_header Connection "";        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;    }     # Dashboard itself — IP-restricted.    location / {        allow 203.0.113.10;        deny all;        proxy_pass http://chomper_ui;        proxy_http_version 1.1;        proxy_set_header Connection "";        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;    }}

The order matters: nginx matches the most specific location prefix, so the agent carve-out above is reached before the restricted / block regardless of the order they're written in the file — but keep the more specific block first for readability anyway.

Apache

<VirtualHost *:443>    ServerName dashboard.example.com     ProxyPreserveHost On    ProxyTimeout 30     <Location "/agent-proxy/network-probes/agent/">        # Public — auth is the module's own key, not the caller IP.        ProxyPass "http://10.0.0.5:3001/agent-proxy/network-probes/agent/" keepalive=On        ProxyPassReverse "http://10.0.0.5:3001/agent-proxy/network-probes/agent/"    </Location>     <Location "/">        Require ip 203.0.113.10        ProxyPass "http://10.0.0.5:3001/" keepalive=On        ProxyPassReverse "http://10.0.0.5:3001/"    </Location></VirtualHost>

Apache evaluates the most specific <Location> match, same principle as nginx above — the agent carve-out wins over the restricted / block for anything under that path.

3. Point agent/ingestion URLs at a port your CDN actually forwards

Free and Pro Cloudflare plans (and similar CDN/WAF products) only proxy a fixed list of ports — 80/443 plus a handful of others. If chomper-ingestion listens on a non-standard port such as :3000, requests routed through the CDN can silently time out even though the port is open and reachable at the host/firewall level.

If your reverse proxy already forwards /api/v1/events on 443 (worth doing anyway, for a single TLS cert to manage), point the module's/agent's ingestion URL at your bare proxied hostname with no port, instead of the container's own :3000:

location /api/v1/events {    proxy_pass http://10.0.0.5:3000/api/v1/events;    proxy_http_version 1.1;    proxy_set_header Connection "";    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}

4. Custom scripts behind a WAF/bot-fight product

If you write your own script or integration that posts events straight to /api/v1/events from behind Cloudflare or a similar product, send an explicit User-Agent header. Some WAFs silently block a generic HTTP client's default identity (for example Python's stock urllib/requests string) even though the request is otherwise correctly authenticated with your X-API-Key — an identical request from curl or a browser passes untouched. Chomper's own probe agent already does this (chomper-probe-agent/1.0); apply the same pattern to anything you build yourself.


Quick reference

SymptomLikely causeFix
Occasional one-shot 502, otherwise everything worksNo upstream keepalive / no timeouts on the proxy→chomper-ui hop§1 — upstream + keepalive + explicit timeouts
Probe agents can't reach their assignment endpoint, dashboard itself loads fineDashboard vhost's IP allowlist also covers /agent-proxy/*§2 — explicit carve-out location/block for /agent-proxy/<slug>/agent/
Network is unreachable against a non-standard ingestion port through a CDNFree/Pro Cloudflare only proxies a fixed port list§3 — proxy ingestion on 443, point the agent/module at the bare host
Custom integration gets blocked before it ever reaches Chomper's own auth checkWAF flags a generic HTTP client's default User-Agent§4 — send an explicit, identifiable User-Agent

Last updated 11 August 2026