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

# verifyngo quickstart: Docker setup

> Run verifyngo as a reverse-proxy bot filter in front of your web service using Docker and a config.json file. No changes to your app are required.

This page walks you through getting verifyngo running in front of your web service in a few minutes. You will create a single `config.json` file, start a Docker container, and point your existing reverse proxy at it.

**1. Create your config file**

Create a `config.json` file in your working directory. The example below covers the essential fields to get up and running.

```json config.json theme={null}
{
  "listen_addr": "0.0.0.0:8080",
  "upstream_url": "http://your-app:3000",
  "cookie_secret": "replace-with-32-byte-hex-secret",
  "provider": "turnstile",
  "turnstile": {
    "site_key": "your-turnstile-site-key",
    "secret_key": "your-turnstile-secret-key"
  },
  "default_action": "challenge"
}
```

> [!NOTE]
>
> * **`upstream_url`** — the address of your actual application. verifyngo forwards every verified request here.
> * **`cookie_secret`** — a random 32-byte hex string used to sign session cookies. Generate one with `openssl rand -hex 32` and never reuse it across deployments.
> * **`provider`** — selects which CAPTCHA provider verifyngo presents to visitors. Supported values are `turnstile`, `hcaptcha`, and `cap`.

**2. Run with Docker**

Start verifyngo as a container, mounting your config file as read-only.

```bash docker run theme={null}
docker run -d \
  -p 8080:8080 \
  -v $(pwd)/config.json:/config.json:ro \
  ghcr.io/chocolatemoo53/verifyngo:latest
```

```yaml docker compose theme={null}
services:
  verifyngo:
    image: ghcr.io/chocolatemoo53/verifyngo:latest
    ports:
      - "8080:8080"
    volumes:
      - ./config.json:/config.json:ro
      - verifyngo-data:/data
    environment:
      - TZ=UTC
    restart: unless-stopped

volumes:
  verifyngo-data:
```

verifyngo is now listening on port `8080` and will proxy verified traffic to the `upstream_url` you configured.

**3. Point your reverse proxy at verifyngo**

Update your Nginx, Caddy, or Traefik configuration to send incoming traffic to `localhost:8080`which is where verifyngo handles the challenge flow and forwards only verified requests upstream.

Here is a minimal Nginx example:

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

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

> [!TIP]
>
> When you have a reverse proxy in front of verifyngo, enable `"trust_real_ip": true` in your `config.json` and add the proxy's IP address to `"trusted_proxies"`. This ensures verifyngo evaluates the real visitor IP rather than the proxy's address.
>
> ```json theme={null}
> "trust_real_ip": true,
> "trusted_proxies": ["127.0.0.1"]
> ```

**4. Test it**

Open your site in a browser. Because `default_action` is set to `challenge`, you will see the CAPTCHA page on your first visit. Solve it once and verifyngo sets a signed cookie.

To confirm everything is working, open a private browsing window and visit your site again. You should see the challenge page. After solving it, subsequent requests in the same browser session should pass straight through to your app.

> [!NOTE]
>
> By default, verifyngo keeps ban and walkaway state in memory, which means that state is lost when the container restarts. For production deployments, set `store.backend` to `"file"` or `"redis"` in your `config.json` so that state persists across restarts. See [Persistence](https://verifyngo.chocolatemoo53.com/configuration/persistence.md) for full details.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.