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 withopenssl rand -hex 32and never reuse it across deployments.provider— selects which CAPTCHA provider verifyngo presents to visitors. Supported values areturnstile,hcaptcha, andcap.
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: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.