> ## Documentation Index
> Fetch the complete documentation index at: https://verifyngo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Put verifyngo behind a reverse proxy: Nginx, Caddy, Traefik

> Set up Nginx, Caddy, or Traefik to send all traffic to verifyngo first, so bot filtering runs before requests reach your upstream app.

verifyngo acts as a proxy itself, so your public-facing reverse proxy should forward traffic to verifyngo, which in turn forwards verified requests to your app. The flow looks like this:

```text theme={null}
visitor → Nginx / Caddy / Traefik → verifyngo :8080 → your upstream app
```

This guide shows minimal config for each of the three most common reverse proxies.

<Tip>
  Whenever you put a reverse proxy in front of verifyngo, enable `trust_real_ip: true` in verifyngo's config and add the proxy's IP to `trusted_proxies`. Without this, verifyngo sees the proxy's IP as the client IP instead of the real visitor's IP, which breaks IP-based rules and ban tracking.
</Tip>

## Proxy configuration

Pick the reverse proxy you're using and follow the snippet for your stack.

<Tabs>
  <Tab title="Nginx">
    Add a `proxy_pass` block that points to verifyngo on `127.0.0.1:8080`. Forward the standard headers so verifyngo can read the real client IP and protocol:

    ```nginx nginx.conf theme={null}
    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass          http://127.0.0.1:8080;
            proxy_set_header    Host              $host;
            proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header    X-Forwarded-Proto $scheme;
        }
    }
    ```

    After editing, test and reload Nginx:

    ```bash theme={null}
    nginx -t && nginx -s reload
    ```
  </Tab>

  <Tab title="Caddy">
    Caddy's `reverse_proxy` directive is all you need. Caddy automatically appends the client's IP to `X-Forwarded-For`, so no extra header configuration is required:

    ```caddy Caddyfile theme={null}
    example.com {
        reverse_proxy 127.0.0.1:8080
    }
    ```

    Reload Caddy after saving:

    ```bash theme={null}
    caddy reload
    ```
  </Tab>

  <Tab title="Traefik">
    If you run verifyngo with Docker Compose alongside a Traefik container, add labels to the `verifyngo` service to register it as a Traefik backend:

    ```yaml docker-compose.yml theme={null}
    services:
      verifyngo:
        image: ghcr.io/chocolatemoo53/verifyngo:latest
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.verifyngo.rule=Host(`example.com`)"
          - "traefik.http.routers.verifyngo.entrypoints=web"
          - "traefik.http.services.verifyngo.loadbalancer.server.port=8080"
    ```

    Traefik forwards `X-Forwarded-For` automatically. Make sure your Traefik instance has `--entryPoints.web.forwardedHeaders.insecure=false` (or equivalent trusted IP config) so the header is not spoofable.
  </Tab>
</Tabs>

## trust\_real\_ip config

After setting up your reverse proxy, update your `config.json` to tell verifyngo to trust the forwarded IP header:

```json config.json theme={null}
{
  "trust_real_ip": true,
  "trusted_proxies": ["127.0.0.1"]
}
```

| Key               | Description                                                                                                                                            |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `trust_real_ip`   | When `true`, verifyngo reads the client IP from `X-Forwarded-For` instead of the TCP connection's remote address.                                      |
| `trusted_proxies` | A list of IPs or CIDR ranges whose `X-Forwarded-For` headers verifyngo will accept. Requests arriving from any other address are treated as untrusted. |

**Automatic trust for private addresses:** if `trusted_proxies` is empty, verifyngo automatically trusts loopback and private-range IPs — specifically any address that is a loopback address or falls within a private IP range. This covers the common case where your reverse proxy and verifyngo run on the same host or inside the same private Docker network.

**Public-IP proxies:** if your proxy connects from a public IP (for example, a cloud load balancer), the automatic trust does not apply. List the proxy's IP explicitly in `trusted_proxies`:

```json config.json theme={null}
{
  "trust_real_ip": true,
  "trusted_proxies": ["203.0.113.42"]
}
```
