Documentation Index Fetch the complete documentation index at: https://mintlify.com/cerbos/cerbos/llms.txt
Use this file to discover all available pages before exploring further.
Cerbos provides official Docker images for easy deployment in containerized environments.
Docker Images
Official Cerbos images are available on GitHub Container Registry:
Image : ghcr.io/cerbos/cerbos
Tags : Version tags (e.g., 0.52.0), latest, dev
Architecture : AMD64 and ARM64
Quick Start
Basic Container
Run Cerbos with default configuration:
docker run -d \
--name cerbos \
-p 3592:3592 \
-p 3593:3593 \
ghcr.io/cerbos/cerbos:latest
With Custom Policies
Mount a local policies directory:
docker run -d \
--name cerbos \
-p 3592:3592 \
-p 3593:3593 \
-v $( pwd ) /policies:/policies \
-e CERBOS_CONFIG=__default__ \
ghcr.io/cerbos/cerbos:latest
With Custom Configuration
Mount a configuration file:
docker run -d \
--name cerbos \
-p 3592:3592 \
-p 3593:3593 \
-v $( pwd ) /config/.cerbos.yaml:/config/.cerbos.yaml \
ghcr.io/cerbos/cerbos:latest server --config=/config/.cerbos.yaml
Dockerfile Details
The official Cerbos Dockerfile:
FROM alpine:3.16 AS base
RUN apk add -U --no-cache ca-certificates && update-ca-certificates
FROM scratch
ARG TARGETPLATFORM
EXPOSE 3592 3593
ENV CERBOS_CONFIG= "__default__"
VOLUME [ "/policies" , "/tmp" , "/.cache" ]
ENTRYpoint [ "/cerbos" ]
CMD [ "server" ]
HEALTHCHECK --interval=10s --timeout=2s --retries=2 CMD [ "/cerbos" , "healthcheck" ]
COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY ${TARGETPLATFORM}/cerbos /cerbos
Key features:
Minimal scratch-based image for security
Multi-architecture support (AMD64, ARM64)
Built-in health check every 10 seconds
Exposed ports: 3592 (HTTP), 3593 (gRPC)
Default volumes for policies, temp, and cache
Ports and Volumes
Exposed Ports
3592 : HTTP API (REST endpoints, health checks, metrics)
3593 : gRPC API (recommended for production)
Volumes
/policies: Policy files directory
/tmp: Temporary files and caches
/.cache: Bundle cache directory (for Hub/remote bundles)
Environment Variables
Default Configuration
When CERBOS_CONFIG=__default__, Cerbos uses:
server :
httpListenAddr : ":3592"
grpcListenAddr : ":3593"
storage :
driver : "disk"
disk :
directory : /policies
watchForChanges : false
Common Variables
Configuration
Storage
Audit
Schema
CERBOS_CONFIG = __default__ # Use default config
CERBOS_LOG_LEVEL = info # Log level: debug, info, warn, error
Docker Compose
Basic Setup
Create docker-compose.yml:
services :
cerbos :
image : ghcr.io/cerbos/cerbos:latest
container_name : cerbos
restart : unless-stopped
ports :
- "3592:3592"
- "3593:3593"
volumes :
- ./policies:/policies
- ./config/.cerbos.yaml:/config/.cerbos.yaml
command : [ "server" , "--config=/config/.cerbos.yaml" ]
healthcheck :
test : [ "/cerbos" , "healthcheck" ]
interval : 10s
timeout : 2s
retries : 3
Start the service:
Production Setup
A production-ready configuration with monitoring:
services :
cerbos :
image : ghcr.io/cerbos/cerbos:0.52.0
container_name : cerbos
restart : always
ports :
- "3592:3592"
- "3593:3593"
volumes :
- ./config:/conf:ro
- ./policies:/policies:ro
- ./audit:/audit
- cerbos-cache:/.cache
command :
- "server"
- "--config=/conf/.cerbos.yaml"
- "--log-level=info"
environment :
- AUDIT_ENABLED=true
- SCHEMA_ENFORCEMENT=reject
deploy :
resources :
limits :
cpus : '2.0'
memory : 512M
reservations :
cpus : '0.5'
memory : 128M
healthcheck :
test : [ "/cerbos" , "healthcheck" ]
interval : 10s
timeout : 2s
retries : 3
start_period : 5s
networks :
- cerbos-network
prometheus :
image : prom/prometheus:latest
container_name : prometheus
ports :
- "9090:9090"
volumes :
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command :
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
networks :
- cerbos-network
depends_on :
- cerbos
grafana :
image : grafana/grafana:latest
container_name : grafana
ports :
- "3000:3000"
volumes :
- ./grafana/dashboards.yaml:/etc/grafana/provisioning/dashboards/dashboards.yaml:ro
- ./grafana/datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
- grafana-data:/var/lib/grafana
environment :
- GF_SECURITY_ADMIN_PASSWORD=admin
networks :
- cerbos-network
depends_on :
- prometheus
volumes :
cerbos-cache :
prometheus-data :
grafana-data :
networks :
cerbos-network :
driver : bridge
Prometheus configuration (prometheus/prometheus.yml):
global :
scrape_interval : 15s
evaluation_interval : 15s
scrape_configs :
- job_name : 'cerbos'
static_configs :
- targets : [ 'cerbos:3592' ]
metrics_path : '/_cerbos/metrics'
With Database Storage
Using PostgreSQL for policy storage:
services :
cerbos :
image : ghcr.io/cerbos/cerbos:latest
container_name : cerbos
restart : always
ports :
- "3592:3592"
- "3593:3593"
volumes :
- ./config:/conf:ro
command : [ "server" , "--config=/conf/.cerbos.yaml" ]
environment :
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=cerbos
- DB_PASSWORD=cerbos
- DB_NAME=cerbos
depends_on :
postgres :
condition : service_healthy
networks :
- cerbos-network
postgres :
image : postgres:14-alpine
container_name : postgres
restart : always
environment :
- POSTGRES_USER=cerbos
- POSTGRES_PASSWORD=cerbos
- POSTGRES_DB=cerbos
volumes :
- postgres-data:/var/lib/postgresql/data
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
ports :
- "5432:5432"
healthcheck :
test : [ "CMD-SHELL" , "pg_isready -U cerbos" ]
interval : 10s
timeout : 5s
retries : 5
networks :
- cerbos-network
volumes :
postgres-data :
networks :
cerbos-network :
driver : bridge
Configuration file for PostgreSQL (config/.cerbos.yaml):
server :
httpListenAddr : ":3592"
grpcListenAddr : ":3593"
storage :
driver : "postgres"
postgres :
url : "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
Configuration
Storage Backends
Disk Storage
Git Storage
Cerbos Hub
PostgreSQL
server :
httpListenAddr : ":3592"
grpcListenAddr : ":3593"
storage :
driver : "disk"
disk :
directory : /policies
watchForChanges : true
TLS Configuration
Enable TLS for secure communication:
server :
httpListenAddr : ":3592"
grpcListenAddr : ":3593"
tls :
cert : /certs/server.crt
key : /certs/server.key
caCert : /certs/ca.crt
Mount certificates:
docker run -d \
--name cerbos \
-p 3592:3592 \
-p 3593:3593 \
-v $( pwd ) /certs:/certs:ro \
-v $( pwd ) /config/.cerbos.yaml:/config/.cerbos.yaml:ro \
ghcr.io/cerbos/cerbos:latest server --config=/config/.cerbos.yaml
Audit Logging
Enable audit logs:
audit :
enabled : true
backend : "file"
file :
path : /audit/audit.log
retentionPeriod : 168h # 7 days
Mount audit directory:
docker run -d \
--name cerbos \
-p 3592:3592 \
-p 3593:3593 \
-v $( pwd ) /audit:/audit \
-v $( pwd ) /config/.cerbos.yaml:/config/.cerbos.yaml:ro \
ghcr.io/cerbos/cerbos:latest server --config=/config/.cerbos.yaml
Health Checks
Built-in Health Check
The Docker image includes a health check:
HEALTHCHECK --interval=10s --timeout=2s --retries=2 \
CMD [ "/cerbos" , "healthcheck" ]
Manual Health Check
# Check container health
docker inspect --format= '{{.State.Health.Status}}' cerbos
# Using curl
docker exec cerbos /cerbos healthcheck
# HTTP endpoint
curl http://localhost:3592/_cerbos/health
Expected response:
Resource Limits
Using Docker Run
docker run -d \
--name cerbos \
--memory= "512m" \
--cpus= "1.0" \
--pids-limit=100 \
-p 3592:3592 \
-p 3593:3593 \
ghcr.io/cerbos/cerbos:latest
Using Docker Compose
services :
cerbos :
image : ghcr.io/cerbos/cerbos:latest
deploy :
resources :
limits :
cpus : '2.0'
memory : 512M
reservations :
cpus : '0.5'
memory : 128M
Networking
Bridge Network (Default)
docker network create cerbos-net
docker run -d \
--name cerbos \
--network cerbos-net \
-p 3592:3592 \
-p 3593:3593 \
ghcr.io/cerbos/cerbos:latest
Host Network
For maximum performance:
docker run -d \
--name cerbos \
--network host \
ghcr.io/cerbos/cerbos:latest
Host networking is only available on Linux and removes network isolation.
Security Best Practices
Run as Non-Root User
The Cerbos image runs as a non-root user by default (scratch-based image).
Read-Only Root Filesystem
docker run -d \
--name cerbos \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
-p 3592:3592 \
-p 3593:3593 \
-v $( pwd ) /policies:/policies:ro \
ghcr.io/cerbos/cerbos:latest
Security Options
docker run -d \
--name cerbos \
--cap-drop=ALL \
--security-opt=no-new-privileges:true \
--read-only \
-p 3592:3592 \
-p 3593:3593 \
ghcr.io/cerbos/cerbos:latest
Docker Compose Security
services :
cerbos :
image : ghcr.io/cerbos/cerbos:latest
read_only : true
security_opt :
- no-new-privileges:true
cap_drop :
- ALL
tmpfs :
- /tmp:rw,noexec,nosuid,size=100m
volumes :
- ./policies:/policies:ro
Monitoring
Container Stats
# Real-time stats
docker stats cerbos
# Logs
docker logs -f cerbos
# Specific time range
docker logs --since 1h cerbos
Prometheus Metrics
Metrics are exposed at http://localhost:3592/_cerbos/metrics:
curl http://localhost:3592/_cerbos/metrics
Key metrics:
cerbos_check_duration_seconds: Authorization check duration
cerbos_check_total: Total authorization checks
cerbos_policy_repo_load_duration_seconds: Policy load time
Troubleshooting
Container Won’t Start
# Check logs
docker logs cerbos
# Inspect container
docker inspect cerbos
# Run interactively
docker run -it --rm \
-v $( pwd ) /config:/config \
ghcr.io/cerbos/cerbos:latest server --config=/config/.cerbos.yaml
Policy Errors
# Validate policies before mounting
docker run --rm \
-v $( pwd ) /policies:/policies \
ghcr.io/cerbos/cerbosctl:latest compile /policies
# Check policy loading
docker logs cerbos | grep -i policy
Permission Issues
# Check volume permissions
ls -la policies/
# Fix permissions
chmod -R 755 policies/
chmod 644 policies/ * .yaml
Port Conflicts
# Check if ports are in use
lsof -i :3592
lsof -i :3593
# Use different ports
docker run -d \
--name cerbos \
-p 13592:3592 \
-p 13593:3593 \
ghcr.io/cerbos/cerbos:latest
Complete Production Example
A complete production setup with all best practices:
services :
cerbos :
image : ghcr.io/cerbos/cerbos:0.52.0
container_name : cerbos-prod
restart : always
hostname : cerbos
# Ports
ports :
- "3592:3592"
- "3593:3593"
# Volumes
volumes :
- ./config/.cerbos.yaml:/config/.cerbos.yaml:ro
- ./policies:/policies:ro
- ./certs:/certs:ro
- ./audit:/audit
- cerbos-cache:/.cache
# Command
command :
- "server"
- "--config=/config/.cerbos.yaml"
- "--log-level=info"
# Environment
environment :
- AUDIT_ENABLED=true
- SCHEMA_ENFORCEMENT=reject
# Security
read_only : true
security_opt :
- no-new-privileges:true
cap_drop :
- ALL
tmpfs :
- /tmp:rw,noexec,nosuid,size=100m
# Resources
deploy :
resources :
limits :
cpus : '2.0'
memory : 512M
reservations :
cpus : '0.5'
memory : 128M
restart_policy :
condition : on-failure
delay : 5s
max_attempts : 3
window : 120s
# Health check
healthcheck :
test : [ "/cerbos" , "healthcheck" ]
interval : 10s
timeout : 2s
retries : 3
start_period : 5s
# Logging
logging :
driver : "json-file"
options :
max-size : "10m"
max-file : "3"
# Network
networks :
- cerbos-network
volumes :
cerbos-cache :
driver : local
networks :
cerbos-network :
driver : bridge
ipam :
config :
- subnet : 172.28.0.0/16
This configuration provides:
Automatic restarts and health checks
Resource limits and security hardening
Persistent cache and audit logs
Proper logging and monitoring
Network isolation