Skip to content

Caddy & Docker Deployment

This guide covers deploying LightHouse using Docker with a Caddy reverse proxy.

Project Layout

📁 caddy/
├──  Caddyfile
├── 📁 config/
└── 📁 data/
 docker-compose.yaml
📁 lighthouse/
├──  config.yaml
└── 📁 data/
    └── 📁 keys/

Configuration Files

services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config

  lighthouse:
    image: oidfed/lighthouse:latest
    restart: unless-stopped
    volumes:
      - ./lighthouse/config.yaml:/config.yaml:ro
      - ./lighthouse/data:/data
lighthouse.example.com {
    reverse_proxy lighthouse:7672
}

For separate admin API access (recommended for production):

# Public federation endpoints
lighthouse.example.com {
    reverse_proxy lighthouse:7672
}

# Admin API (restrict access via firewall or Caddy matchers)
admin.lighthouse.example.com {
    reverse_proxy lighthouse:7673
}
server:
  port: 7672

# Entity identifier - CHANGE THIS to your domain
entity_id: "https://lighthouse.example.com"

# Signing configuration
signing:
  kms: filesystem
  pk_backend: db
  auto_generate_keys: true
  filesystem:
    key_dir: "/data/keys"

# Storage configuration
storage:
  driver: sqlite
  data_dir: "/data"

# Admin API
api:
  admin:
    enabled: true
    users_enabled: true

# Federation endpoints
endpoints:
  fetch:
    path: "/fetch"
  list:
    path: "/list"
  resolve:
    path: "/resolve"
  trust_mark:
    path: "/trustmark"
  trust_mark_status:
    path: "/trustmark/status"
  trust_mark_list:
    path: "/trustmark/list"
  historical_keys:
    path: "/historical-keys"

For more configuration options, see Configuration.

Project Layout

📁 caddy/
├──  Caddyfile
├── 📁 config/
└── 📁 data/
 docker-compose.yaml
📁 lighthouse/
├──  config.yaml
└── 📁 data/
    └── 📁 keys/
📁 postgres/
└── 📁 data/

Configuration Files

services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/data:/data
      - ./caddy/config:/config

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: lighthouse
      POSTGRES_PASSWORD: changeme  # Change this!
      POSTGRES_DB: lighthouse
    volumes:
      - ./postgres/data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U lighthouse"]
      interval: 5s
      timeout: 5s
      retries: 5

  lighthouse:
    image: oidfed/lighthouse:latest
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      LH_STORAGE_DSN: "host=postgres user=lighthouse password=changeme dbname=lighthouse sslmode=disable"
    volumes:
      - ./lighthouse/config.yaml:/config.yaml:ro
      - ./lighthouse/data:/data
lighthouse.example.com {
    reverse_proxy lighthouse:7672
}

For separate admin API access (recommended for production):

# Public federation endpoints
lighthouse.example.com {
    reverse_proxy lighthouse:7672
}

# Admin API (restrict access via firewall or Caddy matchers)
admin.lighthouse.example.com {
    reverse_proxy lighthouse:7673
}
server:
  port: 7672

# Entity identifier - CHANGE THIS to your domain
entity_id: "https://lighthouse.example.com"

# Signing configuration
signing:
  kms: filesystem
  pk_backend: db
  auto_generate_keys: true
  filesystem:
    key_dir: "/data/keys"

# Storage configuration
storage:
  driver: postgres
  # DSN set via LH_STORAGE_DSN environment variable in docker-compose.yaml

# Admin API
api:
  admin:
    enabled: true
    users_enabled: true
    # Separate port for admin API (optional)
    # port: 7673

# Federation endpoints
endpoints:
  fetch:
    path: "/fetch"
  list:
    path: "/list"
  resolve:
    path: "/resolve"
  trust_mark:
    path: "/trustmark"
  trust_mark_status:
    path: "/trustmark/status"
  trust_mark_list:
    path: "/trustmark/list"
  historical_keys:
    path: "/historical-keys"

# Statistics (optional, recommended for production)
stats:
  enabled: true
  retention:
    detailed_days: 90
    aggregated_days: 365

For more configuration options, see Configuration.

Environment Variables

Configuration can also be passed via environment variables:

environment:
  LH_STORAGE_DSN: "host=postgres user=lighthouse password=${DB_PASSWORD} dbname=lighthouse"
  LH_ENTITY_ID: "https://lighthouse.example.com"

See Configuration for details.

Initial Setup

After starting the containers with docker compose up -d, configure your federation entity using the Admin API.

1. Create an Admin User

# Via the CLI inside the container
docker compose exec lighthouse lighthouse passwd

# Or via API (basic auth disabled initially if no users exist)
curl -X POST https://lighthouse.example.com/api/v1/admin/users \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-secure-password"}'

2. Configure Federation Metadata

curl -X PUT https://lighthouse.example.com/api/v1/admin/entity-configuration/metadata/federation_entity \
  -u admin:your-secure-password \
  -H "Content-Type: application/json" \
  -d '{
    "organization_name": "Example Organization",
    "homepage_uri": "https://example.com",
    "contacts": ["admin@example.com"]
  }'

3. Set Authority Hints (if not a Trust Anchor)

curl -X POST https://lighthouse.example.com/api/v1/admin/entity-configuration/authority-hints \
  -u admin:your-secure-password \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "https://trust-anchor.example.org"}'

4. Configure Trust Mark Issuance (optional)

curl -X POST https://lighthouse.example.com/api/v1/admin/trust-marks/issuance-spec \
  -u admin:your-secure-password \
  -H "Content-Type: application/json" \
  -d '{
    "trust_mark_type": "https://lighthouse.example.com/trustmarks/member",
    "lifetime": "8760h"
  }'

Verification

Check that LightHouse is running correctly:

# Fetch entity configuration
curl https://lighthouse.example.com/.well-known/openid-federation

# Check Admin API
curl https://lighthouse.example.com/api/v1/admin/entity-configuration \
  -u admin:your-secure-password

Next Steps