Skip to main content
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 — no changes to your app required.
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.
config.json
  • 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.
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 — where verifyngo is listening — instead of directly to your app. verifyngo handles the challenge flow and forwards only verified requests upstream. Your application code does not need to change.Here is a minimal Nginx example:
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.
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 — you won’t be challenged again until that cookie expires (the default is 7 days, controlled by cookie_ttl).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.
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 for full details.