# Proxy with Nginx

> Serve the MetricRaven script and events through Nginx with two location blocks.

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

Two exact-match location blocks relay the script and events, sending only the headers MetricRaven needs.

## Set it up

1. **Create the shared proxy settings**

   ```nginx title="/etc/nginx/snippets/metricraven-proxy.conf"
   # /etc/nginx/snippets/metricraven-proxy.conf
   proxy_ssl_server_name on;
   proxy_http_version 1.1;
   # Send only what the collector needs; your site's cookies stay on your server.
   proxy_pass_request_headers off;
   proxy_set_header Host metricraven.com;
   proxy_set_header Content-Type $content_type;
   proxy_set_header Origin $http_origin;
   proxy_set_header User-Agent $http_user_agent;
   # The visitor's IP. Behind a CDN or load balancer, configure the realip module first.
   proxy_set_header X-Visitor-IP $remote_addr;
   ```

2. **Add the locations to your server block**

   ```nginx title="sites-available/example.com"
   # Inside your site's existing server { } block
   location = /a/script {
       limit_except GET { deny all; }
       proxy_pass https://metricraven.com/js/script.js;
       include /etc/nginx/snippets/metricraven-proxy.conf;
       proxy_hide_header Cache-Control;
       add_header Cache-Control "public, max-age=3600" always;
   }

   location = /a/event {
       limit_except POST { deny all; }
       proxy_pass https://metricraven.com/api/v1/collect;
       include /etc/nginx/snippets/metricraven-proxy.conf;
       proxy_hide_header Cache-Control;
       add_header Cache-Control "no-store" always;
   }
   ```

3. **Test and reload**

   ```bash
   sudo nginx -t && sudo systemctl reload nginx
   ```

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

- `proxy_ssl_server_name on` is required: MetricRaven is served over HTTPS behind a CDN that needs the hostname during the TLS handshake.
- Behind a CDN or load balancer, `$remote_addr` is that proxy. Configure `set_real_ip_from` and `real_ip_header` (the realip module) so it becomes the visitor.
- `proxy_pass_request_headers off` stops Nginx from forwarding your site's cookies. The headers set after it are the only ones sent.

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.
