Set up StyloBot: illustrated guide
This is the ten-minute path to a working StyloBot gateway in front of an existing app, from a single Docker Compose file to a licensed, dashboard-managed fleet. Every command here was tested against the real gateway image — nothing in this guide documents a feature that does not exist.
The full reference pages live alongside this one: add to Docker Compose, running locally, configuration, how StyloBot works.
What you are building
flowchart LR
client[Visitors] -->|public port 8080| gw[StyloBot gateway]
gw -->|detection pipeline| app[Your app on the Compose network]
gw -.observe mode: pass-through.-> client
subgraph optional["Optional: commercial"]
pg[(PostgreSQL)]
gw <-->|persistence + fleet state| pg
dash[Commercial dashboard]
gw <-->|telemetry| dash
end
The gateway is the only public HTTP port. Your app stops publishing its own port and lives on the internal Compose network; every request passes the detection pipeline first. Start in observe mode (detection runs, nothing is blocked), confirm traffic, then choose an enforcement policy.
1. Add the gateway to an existing compose stack
Take an existing compose.yml with an app service. Remove the app's ports:
entry (keep expose:) and add the gateway service:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
ports:
- "8080:8080"
environment:
ASPNETCORE_URLS: http://+:8080
DEFAULT_UPSTREAM: http://app:3000
depends_on:
- app
app:
image: my-company/my-app:latest
expose:
- "3000"
DEFAULT_UPSTREAM is the zero-config entry point: the gateway builds a catch-all
route to that URL. Replace app:3000 with your service name and port — the
gateway calls the upstream by Compose service name, never localhost (that
would be the gateway container itself). Do not publish both app and
stylobot: callers could then bypass detection entirely.
docker compose up -d app stylobot
sequenceDiagram
participant C as Visitor
participant G as Stylobot gateway
participant A as Your app
C->>G: request
G->>G: detection pipeline (67 detectors)
alt observe mode
G->>A: forward unchanged
else enforce mode
G-->>A: block / challenge / throttle
end
A-->>C: response
Point your existing reverse proxy, load balancer, or DNS at host port 8080.
Your app receives the verdict in headers — X-Bot-Detected,
X-Bot-Confidence, X-Bot-Detection-Probability — with zero latency overhead.
2. Variant A — zero-config default (no database)
Nothing to configure: with no DB_PROVIDER set, the gateway runs detection
with in-process state. This is the whole story for one node — the same engine,
the same detectors, no extra services:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
ports:
- "8080:8080"
environment:
ASPNETCORE_URLS: http://+:8080
DEFAULT_UPSTREAM: http://app:3000
volumes:
- stylobot-data:/app/data
depends_on:
- app
volumes:
stylobot-data:
The /app/data volume keeps the gateway's certificates and logs across
restarts. Observe mode is the default: BotDetection:BlockDetectedBots is
false, so nothing is blocked until you say so. Watch the per-request verdicts
in the container logs, then flip to enforcement (see the
configuration reference for every key).
Kill switch — disable everything if it malfunctions
Two levels of shutoff, both effective immediately on restart:
Full disable — pass everything through untouched. The master switch:
BotDetection:Enableddefaults totrue; set it tofalseand the middleware does not run detection at all — requests pass straight to the upstream, no headers, no throttling:environment: BotDetection__Enabled: "false"Observe-only — detection runs, nothing is ever blocked. This is the shipped default:
BotDetection:BlockDetectedBotsisfalse. The pipeline scores every request and injects theX-Bot-*headers, but never blocks, challenges, or throttles. Use this while you trust the verdicts, or as a softer rollback than the full switch.
Where SQLite fits: the standalone gateway's supported database providers are Postgres and SqlServer (set via
DB_PROVIDER). The SQLite you see in the marketing copy is the ASP.NET pack's default store — embed StyloBot in a .NET app with add to ASP.NET Core and SQLite is the file-backed default there. Single Site, the entry commercial tier, ships that pack with SQLite out of the box (why Single Site).
3. Variant B — PostgreSQL
SQLite-free single-node in-memory is right for one host. When several gateways write shared session and signature state, or your history outgrows the process, move to PostgreSQL. The FOSS gateway takes its database from two env vars:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
ports:
- "8080:8080"
environment:
ASPNETCORE_URLS: http://+:8080
DEFAULT_UPSTREAM: http://app:3000
DB_PROVIDER: Postgres
DB_CONNECTION_STRING: Host=postgres;Database=stylobot;Username=stylobot;Password=${POSTGRES_PASSWORD}
depends_on:
- app
- postgres
postgres:
image: postgres:16
environment:
POSTGRES_DB: stylobot
POSTGRES_USER: stylobot
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
The commercial gateway (license-gated) uses its own persistence wiring —
BotDetection__Commercial__Postgres__ConnectionString plus
StyloBotDashboard__PostgreSQL__ConnectionString for the dashboard's telemetry
store, with StyloBotDashboard__PostgreSQL__AutoInitializeSchema=true — see
the dashboard setup below.
4. HTTPS — built-in LetsEncrypt, or your own certificates
The gateway terminates TLS itself — no Caddy, no separate reverse proxy required. Three TLS modes, all env-driven:
4a. Automatic LetsEncrypt certificates
Set the domain and an ACME account email; the gateway obtains and renews the
certificate automatically, storing it in /app/data/certs:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
ports:
- "443:8443"
environment:
ASPNETCORE_URLS: http://+:8080
DEFAULT_UPSTREAM: http://app:3000
GATEWAY_HTTPS_DOMAIN: gateway.example.com
GATEWAY_HTTPS_ACME_EMAIL: you@example.com
GATEWAY_HTTPS_ACME_CERT_STORE: /app/data/certs
volumes:
- stylobot-data:/app/data
The HTTPS listener is on GATEWAY_HTTPS_PORT (default 8443). DNS for
gateway.example.com must already point at the host before the ACME challenge
can complete.
4b. Existing certificates (files or PFX)
Bring your own cert as a PEM pair or a password-protected PFX:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
ports:
- "443:8443"
environment:
ASPNETCORE_URLS: http://+:8080
DEFAULT_UPSTREAM: http://app:3000
GATEWAY_HTTPS_CERT_PATH: /certs/fullchain.pem
GATEWAY_HTTPS_CERT_KEY_PATH: /certs/privkey.pem
# or a PFX: GATEWAY_HTTPS_CERT_PATH=/certs/gateway.pfx + GATEWAY_HTTPS_CERT_PASSWORD=...
volumes:
- ./certs:/certs:ro
Certificates are read from the mounted files — renew them in place and restart the gateway.
4c. Upstreams over TLS
The upstream can be HTTPS too — DEFAULT_UPSTREAM: https://app:3000 works the
same way. The usual pitfall is the internal upstream using a self-signed or
internal-CA certificate; the gateway validates upstream certificates, so either
present a certificate the gateway trusts, or terminate TLS at the gateway
(4a/4b) and keep the internal hop plain HTTP — the recommended shape for
Compose networks.
flowchart LR
V[Visitor] -->|443 TLS| G[Gateway 8443]
G -->|80 plain, internal| A[Your app]
5. Commercial dashboard — licensing and what it unlocks
The commercial gateway is license-gated. Everything underneath is the same AGPL engine; the license unlocks the management surface.
Get a license. A 30-day trial is issued from the site (start a free trial), or buy a plan (pricing). The portal mints an Ed25519-signed token bound to your account.
Activate it — set the token the gateway validates:
services:
stylobot:
image: scottgal/stylobot-gateway:latest
environment:
BotDetection__Commercial__LicenseToken: ${STYLOBOT_LICENSE_TOKEN}
The token's signed payload carries the tier, expiry, and feature flags; a gateway without a token (or with an expired one) runs the FOSS feature set.
What the license unlocks:
- Live config editing with hot reload (edit policy in the dashboard, applied without restarting the gateway)
- The reporting dashboard: traffic, sessions, fingerprints, per-domain policy
- The ASP.NET, log, and OTel packs for a .NET stack
- Postgres persistence, Redis pub/sub coordination, fleet management and the control plane
Tiers differ in scale and management, never in detection quality — the FOSS engine is identical on every tier. The tier pages spell out the differences: Single Site, Startup, Enterprise.
Next steps
- Watch a live verdict on your own request: the dashboard on stylo.bot is a real gateway running this exact pipeline.
- Troubleshooting: Docker troubleshooting, cloudflare tunnel, Kubernetes.