Support

Self-hosting

aiCaptcha is self-hostable. This page takes you from a fresh machine to a running production instance — for your own use or as the provider for your clients' sites.

Just want to protect your site?

If someone else hosts an aiCaptcha instance for you, you don't need any of this — go straight to the Installation guide.

Requirements

  • Node.js 20+ (Node 22/24 recommended) and npm
  • MySQL 5.7+ or MySQL 8 (a dedicated database)
  • Redis 6+ — optional but recommended for the token cache in multi-instance setups
  • OS: Linux, macOS or Windows

1. Get the code

terminal
git clone <your-repo-url> aicaptcha
cd aicaptcha/next
npm install

2. Configure the environment

Create a .env file in the project root (next/):

.env
# MySQL connection (user needs CREATE/ALTER rights for first-time setup)
DATABASE_URL="mysql://user:password@localhost:3306/aicaptcha"

# Auth secret — generate one:  openssl rand -base64 32
BETTER_AUTH_SECRET="change-me-to-a-long-random-string"

# Public origin of THIS instance (used in snippets, emails and auth links)
NEXT_PUBLIC_APP_URL="https://captcha.yourdomain.com"

# Optional — token cache. Falls back to in-memory when absent.
REDIS_URL="redis://127.0.0.1:6379"
VariableRequiredDescription
DATABASE_URLYesMySQL connection string.
BETTER_AUTH_SECRETYesSigns auth sessions. Keep it secret.
NEXT_PUBLIC_APP_URLYesPublic origin of the instance.
REDIS_URLNoToken cache; in-memory fallback is used when absent.

3. Create the database

mysql
CREATE DATABASE aicaptcha CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'aicaptcha'@'localhost' IDENTIFIED BY 'strong-password';
GRANT ALL PRIVILEGES ON aicaptcha.* TO 'aicaptcha'@'localhost';
FLUSH PRIVILEGES;

4. Create tables & demo data

terminal
# Apply the Prisma schema to MySQL
npm run db:push

# Optional: seed a demo account + demo sites
# (demo@aicaptcha.site / password123)
npm run db:seed

Both commands are combined in npm run setup. The schema creates six tables: users, auth_sessions, auth_accounts, auth_verifications, sites and verifications.

5. Run it

Development

terminal
npm run dev
# → http://localhost:3000

Production

terminal
npm run build
npm start        # serves on port 3000, override with PORT=8080

Before going live

  • Set a unique, long BETTER_AUTH_SECRET.
  • Set NEXT_PUBLIC_APP_URL to your real public origin — the integration snippets shown in the dashboard are generated from it.
  • Point your reverse proxy at port 3000 and enable HTTPS. The widget and API must be served over HTTPS when embedded on HTTPS sites.

6. Reverse proxy (nginx)

/etc/nginx/sites-available/captcha
server {
    listen 443 ssl http2;
    server_name captcha.yourdomain.com;

    # ssl_certificate ...; ssl_certificate_key ...;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The rate limiter reads X-Forwarded-For, so keep that header set correctly.

7. Keep it running (systemd)

/etc/systemd/system/aicaptcha.service
[Unit]
Description=aiCaptcha
After=network.target mysql.service

[Service]
WorkingDirectory=/var/www/aicaptcha/next
ExecStart=/usr/bin/npm start
Environment=NODE_ENV=production
Restart=always

[Install]
WantedBy=multi-user.target
terminal
sudo systemctl enable --now aicaptcha

Updating

terminal
git pull
npm install
npx prisma generate
npx prisma db push   # applies additive schema changes
npm run build
sudo systemctl restart aicaptcha

What's next?