API
Overview
The BunkerWeb API is the control plane used to manage BunkerWeb instances programmatically: list and manage instances, reload/stop, handle bans, plugins, jobs, configs, and more. It exposes a documented FastAPI application with strong authentication, authorization and rate limiting.
Open the interactive documentation at /docs (or <root_path>/docs if you set API_ROOT_PATH). The OpenAPI schema is available at /openapi.json.
Security
The API is a privileged control plane. Do not expose it on the public Internet without additional protections.
At a minimum, restrict source IPs (API_WHITELIST_IPS), enable authentication (API_TOKEN or API users + Biscuit), and consider putting it behind BunkerWeb with an unguessable path and extra access controls.
Prerequisites
The API service requires access to the BunkerWeb database (DATABASE_URI). It is usually deployed alongside the Scheduler and optionally the Web UI. The recommended setup is to run BunkerWeb in front as a reverse proxy and isolate the API on an internal network.
See the quickstart wizard and architecture guidance in the quickstart guide.
Recommended Deployment (Dedicated Containers)
For production, deploy the API as its own container next to the BunkerWeb data plane and scheduler. Keep the API bound to the internal control-plane network and publish it only through BunkerWeb as a reverse proxy. This layout matches the Docker integration reference and ensures the scheduler, BunkerWeb, and API share the same settings.
x-bw-env: &bw-env
# We use an anchor to avoid repeating the same settings for both services
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" # Make sure to set the correct IP range so the scheduler can send the configuration to the instance
DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Remember to set a stronger password for the database
services:
bunkerweb:
# This is the name that will be used to identify the instance in the Scheduler
image: bunkerity/bunkerweb:1.6.6-rc2
ports:
- "80:8080/tcp"
- "443:8443/tcp"
- "443:8443/udp" # For QUIC / HTTP3 support
environment:
<<: *bw-env # We use the anchor to avoid repeating the same settings for all services
restart: "unless-stopped"
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.6.6-rc2
environment:
<<: *bw-env
BUNKERWEB_INSTANCES: "bunkerweb" # Make sure to set the correct instance name
SERVER_NAME: "api.example.com" # Change it if needed
MULTISITE: "yes"
USE_REDIS: "yes"
REDIS_HOST: "redis"
api.example.com_USE_TEMPLATE: "bw-api"
api.example.com_GENERATE_SELF_SIGNED_SSL: "yes"
api.example.com_USE_REVERSE_PROXY: "yes"
api.example.com_REVERSE_PROXY_URL: "/"
api.example.com_REVERSE_PROXY_HOST: "http://bw-api:8888"
volumes:
- bw-storage:/data # This is used to persist the cache and other data like the backups
restart: "unless-stopped"
networks:
- bw-universe
- bw-db
bw-api:
image: bunkerity/bunkerweb-api:1.6.6-rc2
environment:
<<: *bw-env
API_USERNAME: "admin"
API_PASSWORD: "Str0ng&P@ss!" # Remember to set a stronger password for the admin user
DEBUG: "1"
restart: "unless-stopped"
networks:
bw-universe:
aliases:
- bw-api
bw-db:
aliases:
- bw-api
bw-db:
image: mariadb:11
# We set the max allowed packet size to avoid issues with large queries
command: --max-allowed-packet=67108864
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: "db"
MYSQL_USER: "bunkerweb"
MYSQL_PASSWORD: "changeme" # Remember to set a stronger password for the database
volumes:
- bw-data:/var/lib/mysql
restart: "unless-stopped"
networks:
- bw-db
redis: # Redis service for the persistence of reports/bans/stats
image: redis:7-alpine
command: >
redis-server
--maxmemory 256mb
--maxmemory-policy allkeys-lru
--save 60 1000
--appendonly yes
volumes:
- redis-data:/data
restart: "unless-stopped"
networks:
- bw-universe
volumes:
bw-data:
bw-storage:
redis-data:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24 # Make sure to set the correct IP range so the scheduler can send the configuration to the instance
bw-services:
name: bw-services
bw-db:
name: bw-db
This isolates the API behind BunkerWeb, keeps traffic on trusted networks, and lets you enforce authentication, allowlists, and rate limits at both the control plane and the exposed hostname.
Highlights
- Instance‑aware: broadcasts operational actions to discovered instances.
- Strong auth: Basic for admins, Bearer admin override, or Biscuit ACL for fine‑grained permissions.
- IP allowlist and flexible per‑route rate limiting.
- Standard health/readiness signals and startup safety checks.
Compose boilerplates
Reverse proxy the API under /api with BunkerWeb.
x-bw-env: &bw-env
# Shared instance control-plane allowlist for BunkerWeb/Scheduler
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
services:
bunkerweb:
image: bunkerity/bunkerweb:1.6.6-rc2
ports:
- "80:8080/tcp"
- "443:8443/tcp"
- "443:8443/udp" # QUIC
environment:
<<: *bw-env
restart: unless-stopped
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.6.6-rc2
environment:
<<: *bw-env
BUNKERWEB_INSTANCES: "bunkerweb" # Match the instance service name
SERVER_NAME: "www.example.com"
MULTISITE: "yes"
DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"
DISABLE_DEFAULT_SERVER: "yes"
# Reverse-proxy the API on /api
www.example.com_USE_REVERSE_PROXY: "yes"
www.example.com_REVERSE_PROXY_URL: "/api"
www.example.com_REVERSE_PROXY_HOST: "http://bw-api:8888"
volumes:
- bw-storage:/data
restart: unless-stopped
networks:
- bw-universe
- bw-db
bw-api:
image: bunkerity/bunkerweb-api:1.6.6-rc2
environment:
DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Use a strong password
API_WHITELIST_IPS: "127.0.0.0/8 10.20.30.0/24" # API allowlist
API_TOKEN: "secret" # Optional admin override token
API_ROOT_PATH: "/api" # Match reverse-proxy path
restart: unless-stopped
networks:
- bw-universe
- bw-db
bw-db:
image: mariadb:11
# Avoid issues with large queries
command: --max-allowed-packet=67108864
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: "db"
MYSQL_USER: "bunkerweb"
MYSQL_PASSWORD: "changeme" # Use a strong password
volumes:
- bw-data:/var/lib/mysql
restart: unless-stopped
networks:
- bw-db
volumes:
bw-data:
bw-storage:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-db:
name: bw-db
Same as above but leveraging the Autoconf service to discover and configure services automatically. The API is exposed under /api using labels on the API container.
x-api-env: &api-env
AUTOCONF_MODE: "yes"
DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Use a strong password
services:
bunkerweb:
image: bunkerity/bunkerweb:1.6.6-rc2
ports:
- "80:8080/tcp"
- "443:8443/tcp"
- "443:8443/udp" # QUIC
environment:
AUTOCONF_MODE: "yes"
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
restart: unless-stopped
networks:
- bw-universe
- bw-services
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:1.6.6-rc2
environment:
<<: *api-env
BUNKERWEB_INSTANCES: "" # Discovered by Autoconf
SERVER_NAME: "" # Filled via labels
MULTISITE: "yes" # Mandatory with Autoconf
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
volumes:
- bw-storage:/data
restart: unless-stopped
networks:
- bw-universe
- bw-db
bw-autoconf:
image: bunkerity/bunkerweb-autoconf:1.6.6-rc2
depends_on:
- bunkerweb
- bw-docker
environment:
<<: *api-env
DOCKER_HOST: "tcp://bw-docker:2375"
restart: unless-stopped
networks:
- bw-universe
- bw-docker
- bw-db
bw-api:
image: bunkerity/bunkerweb-api:1.6.6-rc2
environment:
<<: *api-env
API_WHITELIST_IPS: "127.0.0.0/8 10.20.30.0/24"
API_TOKEN: "secret"
API_ROOT_PATH: "/api"
labels:
- "bunkerweb.SERVER_NAME=www.example.com"
- "bunkerweb.USE_REVERSE_PROXY=yes"
- "bunkerweb.REVERSE_PROXY_URL=/api"
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-api:8888"
restart: unless-stopped
networks:
- bw-universe
- bw-db
bw-db:
image: mariadb:11
command: --max-allowed-packet=67108864
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: "db"
MYSQL_USER: "bunkerweb"
MYSQL_PASSWORD: "changeme"
volumes:
- bw-data:/var/lib/mysql
restart: unless-stopped
networks:
- bw-db
bw-docker:
image: tecnativa/docker-socket-proxy:nightly
environment:
CONTAINERS: "1"
LOG_LEVEL: "warning"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
networks:
- bw-docker
volumes:
bw-data:
bw-storage:
networks:
bw-universe:
name: bw-universe
ipam:
driver: default
config:
- subnet: 10.20.30.0/24
bw-services:
name: bw-services
bw-db:
name: bw-db
bw-docker:
name: bw-docker
Reverse proxy path
Keep the API path unguessable and combine with the API allowlist and authentication.
If you already expose another app on the same server name with a template (e.g. USE_TEMPLATE), prefer a separate hostname for the API to avoid conflicts.
All‑In‑One
If you use the All‑In‑One image, the API can be enabled by setting SERVICE_API=yes:
docker run -d \
--name bunkerweb-aio \
-e SERVICE_API=yes \
-e API_WHITELIST_IPS="127.0.0.0/8" \
-p 80:8080/tcp -p 443:8443/tcp -p 443:8443/udp \
bunkerity/bunkerweb-all-in-one:1.6.6-rc2
Authentication
Supported ways to authenticate requests:
- Basic admin: When credentials belong to an admin API user, protected endpoints accept
Authorization: Basic <base64(username:password)>. - Admin Bearer override: If
API_TOKENis configured,Authorization: Bearer <API_TOKEN>grants full access. - Biscuit token (recommended): Obtain a token from
POST /authusing Basic credentials or a JSON/form body containingusernameandpassword. Use the returned token asAuthorization: Bearer <token>on subsequent calls.
Example: get a Biscuit, list instances, then reload all instances.
# 1) Get a Biscuit token with admin credentials
TOKEN=$(curl -s -X POST -u admin:changeme http://api.example.com/auth | jq -r .token)
# 2) List instances
curl -H "Authorization: Bearer $TOKEN" http://api.example.com/instances
# 3) Reload configuration across all instances (no test)
curl -X POST -H "Authorization: Bearer $TOKEN" \
"http://api.example.com/instances/reload?test=no"
Biscuit facts and checks
Tokens embed facts like user(<username>), client_ip(<ip>), domain(<host>), and a coarse role role("api_user", ["read", "write"]) derived from DB permissions. Admins include admin(true) while non‑admins carry fine‑grained facts such as api_perm(<resource_type>, <resource_id|*>, <permission>).
Authorization maps the route/method to required permissions; admin(true) always passes. When fine‑grained facts are absent, the guard falls back to the coarse role: GET/HEAD/OPTIONS require read; write verbs require write.
Keys are stored at /var/lib/bunkerweb/.api_biscuit_private_key and /var/lib/bunkerweb/.api_biscuit_public_key. You can also provide BISCUIT_PUBLIC_KEY/BISCUIT_PRIVATE_KEY via environment variables; if neither files nor env are set, the API generates a key pair at startup and persists it securely.
Permissions (ACL)
This API supports two authorization layers:
- Coarse role: Tokens carry
role("api_user", ["read"[, "write"]])for endpoints without a fine‑grained mapping. Read maps to GET/HEAD/OPTIONS; write maps to POST/PUT/PATCH/DELETE. - Fine‑grained ACL: Tokens embed
api_perm(<resource_type>, <resource_id|*>, <permission>)and routes declare what they require.admin(true)bypasses all checks.
Supported resource types: instances, global_config, services, configs, plugins, cache, bans, jobs.
Permission names by resource type:
- instances:
instances_read,instances_update,instances_delete,instances_create,instances_execute - global_config:
global_config_read,global_config_update - services:
service_read,service_create,service_update,service_delete,service_convert,service_export - configs:
configs_read,config_read,config_create,config_update,config_delete - plugins:
plugin_read,plugin_create,plugin_delete - cache:
cache_read,cache_delete - bans:
ban_read,ban_update,ban_delete,ban_created - jobs:
job_read,job_run
Resource IDs: For fine‑grained checks, the second path segment is treated as resource_id when meaningful. Examples: /services/{service} -> {service}; /configs/{service}/... -> {service}. Use "*" (or omit) to grant globally for a resource type.
User and ACL configuration:
- Admin user: Set
API_USERNAMEandAPI_PASSWORDto create the first admin at startup. To rotate creds later, setOVERRIDE_API_CREDS=yes(or ensure the admin was created with methodmanual). Only one admin exists; additional attempts fall back to non‑admin creation. - Non‑admin users and grants: Provide
API_ACL_BOOTSTRAP_FILEpointing to a JSON file, or mount/var/lib/bunkerweb/api_acl_bootstrap.json. The API reads it at startup to create/update users and permissions. - ACL cache file: A read‑only summary is written at
/var/lib/bunkerweb/api_acl.jsonat startup for introspection; authorization evaluates DB‑backed grants baked into the Biscuit token.
Bootstrap JSON examples (both forms supported):
{
"users": {
"ci": {
"admin": false,
"password": "Str0ng&P@ss!",
"permissions": {
"services": {
"*": { "service_read": true },
"app-frontend": { "service_update": true, "service_delete": false }
},
"configs": {
"app-frontend": { "config_read": true, "config_update": true }
}
}
},
"ops": {
"admin": false,
"password_hash": "$2b$13$...bcrypt-hash...",
"permissions": {
"instances": { "*": { "instances_execute": true } },
"jobs": { "*": { "job_run": true } }
}
}
}
}
Or list form:
{
"users": [
{
"username": "ci",
"password": "Str0ng&P@ss!",
"permissions": [
{ "resource_type": "services", "resource_id": "*", "permission": "service_read" },
{ "resource_type": "services", "resource_id": "app-frontend", "permission": "service_update" }
]
}
]
}
Notes:
- Passwords may be plaintext (
password) or bcrypt (password_hash/password_bcrypt). Weak plaintext passwords are rejected in non‑debug builds; if missing, a random one is generated and a warning is logged. resource_id: "*"(or null/empty) grants globally on that resource type.- Existing users can have passwords updated and additional grants applied via bootstrap.
Feature reference
The API is organised by resource-focused routers. Use the sections below as a capability map; the interactive schema at /docs documents request/response models in detail.
Core and authentication
GET /ping,GET /health: lightweight liveness probes for the API service itself.POST /auth: exchange Basic credentials (or the admin override token) for a Biscuit. Accepts JSON, form, orAuthorizationheaders. Admins may also continue using HTTP Basic directly on protected routes when desired.
Instances control plane
GET /instances: list registered instances, including creation/last-seen timestamps, registration method, and metadata.POST /instances: register a new API-managed instance (hostname, optional port, server name, friendly name, method).GET /instances/{hostname}/PATCH /instances/{hostname}/DELETE /instances/{hostname}: inspect, update mutable fields, or remove API-managed instances.DELETE /instances: bulk removal; skips non-API instances and reports them inskipped.GET /instances/pingandGET /instances/{hostname}/ping: health checks across all or individual instances.POST /instances/reload?test=yes|no,POST /instances/{hostname}/reload: trigger configuration reloads (test mode performs dry-run validation).POST /instances/stop,POST /instances/{hostname}/stop: relay stop commands to instances.
Global configuration
GET /global-config: fetch non-default settings (usefull=truefor the entire config,methods=trueto include provenance).PATCH /global-config: upsert API-owned (method="api") global settings; validation errors call out unknown or read-only keys.
Service lifecycle
GET /services: enumerate services with metadata, including draft status and timestamps.GET /services/{service}: retrieve non-default overlays (full=false) or the full config snapshot (full=true) for a service.POST /services: create services, optionally as draft, and seed prefixed variables ({service}_{KEY}). Updates theSERVER_NAMEroster atomically.PATCH /services/{service}: rename services, toggle draft flags, and update prefixed variables. Ignores direct edits toSERVER_NAMEwithinvariablesfor safety.DELETE /services/{service}: remove a service and its derived configuration keys.POST /services/{service}/convert?convert_to=online|draft: quickly switch draft/online state without altering other variables.
Custom configuration snippets
GET /configs: list custom config fragments (HTTP/server/stream/ModSecurity/CRS hooks) for a service (service=globalby default).with_data=trueembeds UTF-8 content when printable.POST /configsandPOST /configs/upload: create new snippets from JSON payloads or uploaded files. Accepted types includehttp,server_http,default_server_http,modsec,modsec_crs,stream,server_stream, and CRS plugin hooks. Names must match^[\w_-]{1,255}$.GET /configs/{service}/{type}/{name}: retrieve a snippet with optional content (with_data=true).PATCH /configs/{service}/{type}/{name}andPATCH .../upload: update or move API-managed snippets; template- or file-managed entries stay read-only.DELETE /configsandDELETE /configs/{service}/{type}/{name}: prune API-managed snippets while preserving template-managed ones, returning askippedlist for ignored entries.
Ban orchestration
GET /bans: aggregate active bans reported by all instances.POST /bansorPOST /bans/ban: apply one or multiple bans. Payloads may be JSON objects, arrays, or stringified JSON.serviceis optional; when omitted the ban is global.POST /bans/unbanorDELETE /bans: remove bans globally or per service using the same flexible payloads.
Plugin management
GET /plugins?type=all|external|ui|pro: list plugins with metadata;with_data=trueincludes packaged bytes when available.POST /plugins/upload: install UI plugins from.zip,.tar.gz, or.tar.xzarchives. Archives may bundle multiple plugins as long as each contains aplugin.json.DELETE /plugins/{id}: remove a UI plugin by ID (^[\w.-]{4,64}$).
Job cache and execution
GET /cache: list cached artifacts produced by scheduler jobs, filtered by service, plugin ID, or job name.with_data=trueincludes printable file content.GET /cache/{service}/{plugin}/{job}/{file}: fetch a specific cache file (download=truestreams an attachment).DELETE /cacheorDELETE /cache/{service}/{plugin}/{job}/{file}: delete cache files and notify the scheduler about affected plugins.GET /jobs: inspect known jobs, their schedule metadata, and cache summaries.POST /jobs/run: request job execution by flagging the associated plugin(s) as changed.
Operational notes
- Write endpoints persist to the shared database; instances pick up changes via scheduler sync or after a
/instances/reload. - Errors are normalised to
{ "status": "error", "message": "..." }with appropriate HTTP status codes (422 validation, 404 not found, 403 ACL, 5xx upstream failures).
Rate limiting
Per‑client rate limiting is handled by SlowAPI. Enable/disable it and shape limits via environment variables or /etc/bunkerweb/api.yml.
API_RATE_LIMIT_ENABLED(default:yes)- Default limit:
API_RATE_LIMIT_TIMESperAPI_RATE_LIMIT_SECONDS(e.g.100per60) API_RATE_LIMIT_RULES: inline JSON/CSV, or a path to a YAML/JSON file with per‑route rules- Storage backend: in‑memory or Redis/Valkey when
USE_REDIS=yesandREDIS_*variables are provided (Sentinel supported) - Headers:
API_RATE_LIMIT_HEADERS_ENABLED(default:yes)
Example YAML (mounted at /etc/bunkerweb/api.yml):
API_RATE_LIMIT_ENABLED: yes
API_RATE_LIMIT_DEFAULTS: ["200/minute"]
API_RATE_LIMIT_RULES:
- path: "/auth"
methods: "POST"
times: 10
seconds: 60
- path: "/instances*"
methods: "GET|POST"
times: 100
seconds: 60
Configuration
You can configure the API via environment variables, Docker secrets, and the optional /etc/bunkerweb/api.yml or /etc/bunkerweb/api.env files. Key settings:
- Docs & schema:
API_DOCS_URL,API_REDOC_URL,API_OPENAPI_URL,API_ROOT_PATH. - Auth basics:
API_TOKEN(admin override Bearer),API_USERNAME/API_PASSWORD(create/update admin),OVERRIDE_API_CREDS. - ACL and users:
API_ACL_BOOTSTRAP_FILE(JSON path). - Biscuit policy:
API_BISCUIT_TTL_SECONDS(0/off disables TTL),CHECK_PRIVATE_IP(bind token to client IP unless private). - IP allowlist:
API_WHITELIST_ENABLED,API_WHITELIST_IPS. - Rate limiting (core):
API_RATE_LIMIT_ENABLED,API_RATE_LIMIT_TIMES,API_RATE_LIMIT_SECONDS,API_RATE_LIMIT_HEADERS_ENABLED. - Rate limiting (advanced):
API_RATE_LIMIT_AUTH_TIMES,API_RATE_LIMIT_AUTH_SECONDS,API_RATE_LIMIT_RULES,API_RATE_LIMIT_DEFAULTS,API_RATE_LIMIT_APPLICATION_LIMITS,API_RATE_LIMIT_STRATEGY,API_RATE_LIMIT_KEY,API_RATE_LIMIT_EXEMPT_IPS,API_RATE_LIMIT_STORAGE_OPTIONS. - Rate limiting storage: in‑memory or Redis/Valkey when
USE_REDIS=yesand Redis settings likeREDIS_HOST,REDIS_PORT,REDIS_PASSWORD,REDIS_DATABASE,REDIS_SSL, or Sentinel variables are set. See the Redis settings table indocs/features.md. - Network/TLS:
API_LISTEN_ADDR,API_LISTEN_PORT,API_FORWARDED_ALLOW_IPS,API_SSL_ENABLED,API_SSL_CERTFILE,API_SSL_KEYFILE,API_SSL_CA_CERTS.
How configuration is loaded
Precedence from highest to lowest:
- Environment variables (e.g. container
environment:or exported shell vars) - Secrets files under
/run/secrets(Docker/K8s secrets; filenames match variable names) - YAML file at
/etc/bunkerweb/api.yml - Env file at
/etc/bunkerweb/api.env(key=value lines) - Built‑in defaults
Notes:
- YAML supports inlining secret files with
<file:relative/path>; the path is resolved against/run/secrets. - Set doc URLs to
off/disabled/noneto disable endpoints (e.g.API_DOCS_URL=off). - If
API_SSL_ENABLED=yes, you must also setAPI_SSL_CERTFILEandAPI_SSL_KEYFILE. - If Redis is enabled (
USE_REDIS=yes), provide Redis details; see Redis section indocs/features.md.
Authentication and users
- Admin bootstrap: set
API_USERNAMEandAPI_PASSWORDto create the first admin. To re‑apply later, setOVERRIDE_API_CREDS=yes. - Non‑admins and permissions: provide
API_ACL_BOOTSTRAP_FILEwith a JSON path (or mount to/var/lib/bunkerweb/api_acl_bootstrap.json). The file may list users and fine‑grained grants. - Biscuit keys: either set
BISCUIT_PUBLIC_KEY/BISCUIT_PRIVATE_KEYor mount files at/var/lib/bunkerweb/.api_biscuit_public_keyand/var/lib/bunkerweb/.api_biscuit_private_key. If none are provided, the API generates and persists a key pair at startup.
TLS and networking
- Bind address/port:
API_LISTEN_ADDR(default0.0.0.0),API_LISTEN_PORT(default8888). - Reverse proxies: set
API_FORWARDED_ALLOW_IPSto the proxy IPs so Gunicorn trustsX‑Forwarded‑*headers. - TLS termination in the API:
API_SSL_ENABLED=yesplusAPI_SSL_CERTFILEandAPI_SSL_KEYFILE; optionalAPI_SSL_CA_CERTS
Rate limiting quick recipes
- Disable globally:
API_RATE_LIMIT_ENABLED=no - Set a simple global limit:
API_RATE_LIMIT_TIMES=100,API_RATE_LIMIT_SECONDS=60 - Per‑route rules: set
API_RATE_LIMIT_RULESto a JSON/YAML file path or inline YAML in/etc/bunkerweb/api.yml.
Startup safety
The API exits if there is no authentication path configured (no Biscuit keys, no admin user, and no API_TOKEN). Ensure at least one method is set before starting.
Startup safety: The API exits if no authentication path is available (no Biscuit keys, no admin API user, and no API_TOKEN). Ensure at least one is configured.
Root path and proxies
If you deploy the API behind BunkerWeb on a sub‑path, set API_ROOT_PATH to that path so /docs and relative routes work correctly when proxied.
Operations
- Health:
GET /healthreturns{"status":"ok"}when the service is up. - Linux service: a
systemdunit namedbunkerweb-api.serviceis packaged. Customize via/etc/bunkerweb/api.envand manage withsystemctl. - Startup safety: the API fails fast when no authentication path is available (no Biscuit keys, no admin user, no
API_TOKEN). Errors are written to/var/tmp/bunkerweb/api.error.