Docker

Fairvisor Edge is distributed as an OCI image and should be run as an immutable container.

Image

  • Runtime: ghcr.io/fairvisor/fairvisor-edge:<tag>

Standalone

services:
  fairvisor-edge:
    image: ghcr.io/fairvisor/fairvisor-edge:v0.1.0
    ports:
      - "8080:8080"
    environment:
      FAIRVISOR_MODE: decision_service
      FAIRVISOR_CONFIG_FILE: /etc/fairvisor/policy.json
    volumes:
      - ./policy.json:/etc/fairvisor/policy.json:ro

SaaS

services:
  fairvisor-edge:
    image: ghcr.io/fairvisor/fairvisor-edge:v0.1.0
    ports:
      - "8080:8080"
    environment:
      FAIRVISOR_MODE: decision_service
      FAIRVISOR_SAAS_URL: https://api.fairvisor.com
      FAIRVISOR_EDGE_ID: edge-prod-us-east-1
      FAIRVISOR_EDGE_TOKEN: fvt_live_xxxxxxxxxxxxx

Sidecar

services:
  my-app:
    image: my-app:latest
    ports:
      - "3000:3000"
    environment:
      FAIRVISOR_URL: http://fairvisor-edge:8080
    depends_on:
      - fairvisor-edge

  fairvisor-edge:
    image: ghcr.io/fairvisor/fairvisor-edge:v0.1.0
    environment:
      FAIRVISOR_MODE: decision_service
      FAIRVISOR_CONFIG_FILE: /etc/fairvisor/policy.json
    volumes:
      - ./policy.json:/etc/fairvisor/policy.json:ro

The app calls POST http://fairvisor-edge:8080/decision per request. No external gateway needed — Fairvisor is network-adjacent but not in the data path.

Reverse proxy

services:
  fairvisor-edge:
    image: ghcr.io/fairvisor/fairvisor-edge:v0.1.0
    ports:
      - "8080:8080"
    environment:
      FAIRVISOR_MODE: reverse_proxy
      FAIRVISOR_BACKEND_URL: http://my-api:3000
      FAIRVISOR_CONFIG_FILE: /etc/fairvisor/policy.json
    volumes:
      - ./policy.json:/etc/fairvisor/policy.json:ro

FAIRVISOR_BACKEND_URL is required in reverse proxy mode.

Health

  • GET /livez
  • GET /readyz

Operational guidance

  • Pin exact image tags in production.
  • Roll upgrades with orchestrator rolling strategy.
⚠️

Restarting a pod resets in-memory counters in lua_shared_dict. Active rate-limit state (token buckets, cost budgets, loop counters) is lost and starts fresh after restart.