Deploy Cap CAPTCHA | Self-Hosted Proof-of-Work CAPTCHA That Passes Its Health Check

Self-host Cap on Railway — proof-of-work CAPTCHA, pinned, health-checked.

Deploy Cap CAPTCHA | Self-Hosted Proof-of-Work CAPTCHA That Passes Its Health Check

Just deployed

/usr/src/app/data

Just deployed

/data

Deploy and Host Cap on Railway

Cap, the open-source proof-of-work CAPTCHA, self-hosted with Valkey. It deploys on the first try: the port, the health check and the volume permissions are set. Every image is pinned.

Nothing to fill in. Open the domain and sign in with the ADMIN_KEY from the Cap service's variables.

About Hosting Cap

Cap protects your forms from bots without tracking your visitors. Instead of picking traffic lights, the visitor's browser solves a small computational puzzle in the background; your server then checks the token with Cap. Two services:

  • Cap: the dashboard, the challenge API the widget talks to, and the siteverify endpoint your backend calls (public)
  • Valkey: site keys, sessions and rate-limit counters, on its own volume, password-protected

Create a site key in the dashboard, add the widget to your page, and verify the token from your backend with the key's secret.

Common Use Cases

  • Sign-up, login and contact forms protected from bots, without Google reCAPTCHA or hCaptcha and their tracking.
  • A CAPTCHA for several sites from one deployment: one site key per site, each with its own difficulty and allowed origins.
  • Rate-limited public APIs that require a solved challenge before an expensive request.

Dependencies for Cap Hosting

Deployment Dependencies

  • Cap tiago2/cap:3.1.14 (public)
  • Valkey valkey/valkey:9.0.6-alpine
  • Cap, by Tiago Rangel and contributors, Apache-2.0. This template only configures the published image.

Implementation Details

  • PORT=3000. Cap listens on 3000 and does not read PORT. Without it, Railway probes the health check on another port and fails the deploy after five minutes, with Cap running fine the whole time. This is why the common Cap template fails four deploys in ten.
  • The health check asks Valkey. /health answers 200 only when Valkey replies to PING, so a deploy that cannot reach its database does not go live.
  • The data volume is writable. The image runs as the unprivileged bun user, and Railway mounts volumes owned by root, so Cap could not save the IP geolocation database it downloads into /usr/src/app/data. RAILWAY_RUN_UID=0 fixes the permissions.
  • Valkey has a password, generated per deployment, and writes snapshots to its volume.
  • Rate limiting sees the real client IP. RATELIMIT_IP_HEADER=x-forwarded-for: Railway's edge replaces any X-Forwarded-For a client sends with the real address, so the first entry cannot be forged to dodge the limit. Checked by sending a forged header through Railway.

Configuration

ADMIN_KEY and the Valkey password are generated. Find ADMIN_KEY in the Cap service's Variables tab; it is the dashboard password, so keep it private.

Verification

Deployed from this template into an empty project, both services starting at once: Cap was live in under a minute, /health returned ok (Cap reached Valkey with its password) and the dashboard answered 200.

Locally, on the same images: admin sign-in, creating a site key, issuing a challenge for it, and the key surviving a restart of both Cap and Valkey. Cap used about 30 MB of memory, well inside the Free plan. The volume fix was checked on a root-owned volume: as bun, writing to it is refused; with UID 0 it works.

Why Deploy Cap on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Cap on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


Template Content

More templates in this category

View Template
Keycloak
Keycloak template with keywind theme + apple and discord providers

beuz
756
View Template
lua-protector
Test deployed my project first

trianaq765-cmd's Project
36
View Template
bknd
Feature-rich yet lightweight backend

10