# Proxy with Caddy

> Serve the MetricRaven script and events through Caddy's reverse_proxy.

Source: https://metricraven.com/docs/proxy-caddy  
Markdown: https://metricraven.com/docs/proxy-caddy.md  
Section: Proxy

Two handle blocks rewrite your paths and reverse-proxy them to MetricRaven.

## Set it up

1. **Add a reusable snippet**

   ```text title="Caddyfile"
   # Top of the same Caddyfile, outside any site block
   (metricraven_upstream) {
   	header_up Host {upstream_hostport}
   	# The visitor's IP. Behind a CDN or load balancer, set trusted_proxies first.
   	header_up X-Visitor-IP {client_ip}
   	header_up -Cookie
   	header_up -Authorization
   	header_up -Referer
   }
   ```

2. **Add the handlers to your site block**

   Replace `example.com` with your existing site address and keep your current directives below the two handlers.

   ```text title="Caddyfile"
   # Caddyfile · Caddy 2.7 or later
   example.com {
   	@metricravenScript {
   		method GET
   		path /a/script
   	}
   	handle @metricravenScript {
   		rewrite * /js/script.js
   		reverse_proxy https://metricraven.com {
   			import metricraven_upstream
   			header_down Cache-Control "public, max-age=3600"
   		}
   	}

   	@metricravenEvent {
   		method POST
   		path /a/event
   	}
   	handle @metricravenEvent {
   		rewrite * /api/v1/collect
   		reverse_proxy https://metricraven.com {
   			import metricraven_upstream
   			header_down Cache-Control "no-store"
   		}
   	}

   	# ...your existing site configuration
   }
   ```

3. **Reload Caddy**

   ```bash
   caddy reload --config /etc/caddy/Caddyfile
   ```

4. **Point your script tag at your own paths**

   Replace your MetricRaven tag with this one. `src` loads the tracker from your domain and `data-api` sends its events there too.

   ```html title="Your website's shared layout"
   <script defer src="/a/script" data-api="/a/event" data-site-id="YOUR_SITE_ID"></script>
   ```

> **Verify it works**
>
> Open your live site. In the browser's Network panel, `/a/script` loads the tracker and `/a/event` answers with `ok: true`. Nothing goes to `metricraven.com` from the browser.
>
> In **Traffic**, your own visit should show your real country and city. If every visit appears to come from your server's or host's location, the visitor IP isn't being forwarded.

## Notes

- `{client_ip}` needs Caddy 2.7 or later. Behind a CDN or load balancer, set `trusted_proxies` in the global `servers` options so it is the visitor, not the proxy.
- `header_up Host {upstream_hostport}` is required for an HTTPS upstream; without it the request reaches MetricRaven with your site's hostname and fails.

How the proxy works and which headers it must send: [Use your own domain](https://metricraven.com/docs/proxy).

## Details

- The proxy forwards only `Content-Type`, `Origin`, `User-Agent` and the visitor's IP as `x-visitor-ip`. Your site's cookies and auth headers never leave your server.
- `Origin` matters: MetricRaven checks it against your site's allowed domains. A missing or wrong origin is refused with `domain_not_allowed`.
- MetricRaven allows about 120 events per minute per visitor IP. Without `x-visitor-ip`, all of your visitors share the proxy's IP, so busy sites lose events as well as locations.
- A proxy doesn't guarantee that every blocker will allow tracking.
