{
  "schema_version": 1,
  "generated_at": "2026-10-22T00:00:00.000Z",
  "canonical_url": "https://openlogs.fyi/tools/lago",
  "slug": "lago",
  "name": "Lago",
  "tagline": "Metering and usage-based billing API with subscription management.",
  "replaces": {
    "summary": "Paid usage-based billing services, such as Stripe Billing and Chargebee.",
    "products": [
      {
        "slug": "chargebee",
        "name": "Chargebee",
        "vendor": "Chargebee",
        "url": "https://openlogs.fyi/alternatives/chargebee"
      },
      {
        "slug": "stripe-billing",
        "name": "Stripe Billing",
        "vendor": "Stripe",
        "url": "https://openlogs.fyi/alternatives/stripe-billing"
      }
    ]
  },
  "stack": [
    {
      "kind": "language",
      "name": "Go"
    },
    {
      "kind": "database",
      "name": "Redis"
    }
  ],
  "deployment_methods": [
    "docker_compose"
  ],
  "requirements": {
    "min_ram_mb": null,
    "min_cpu_cores": null,
    "source_url": null
  },
  "license": {
    "spdx": "AGPL-3.0",
    "class": "osi",
    "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/LICENSE"
  },
  "business_model": {
    "value": "unknown",
    "notes": "The README at the pinned commit does not state a business model, so it stays unknown.",
    "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/README.md",
    "checked_at": "2026-10-22"
  },
  "difficulty": {
    "value": "hard",
    "reason": "8 services (1 database or broker: redis), 3 volume mounts, 5 env values to set, no elevated host access. Heuristic score 7 of 11: hard."
  },
  "repository": {
    "owner": "getlago",
    "name": "lago",
    "url": "https://github.com/getlago/lago"
  },
  "compose_check": {
    "status": "config_ok",
    "validated_at": "2026-10-22",
    "summary": "config_ok on 2026-10-22"
  },
  "recipe": {
    "version": 1,
    "source_path": "docker-compose.yml",
    "source_repo": "getlago/lago",
    "source_commit_sha": "117b8219da7ad92631d47018ace3896f26201161",
    "source_kind": "app_repo",
    "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml"
  },
  "install_steps": [
    {
      "order": 1,
      "kind": "prerequisite",
      "language": "text",
      "label": "Docker with the Compose plugin",
      "body": "A host with Docker and the Docker Compose plugin. This entry runs from a compose file.",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "validation_status": "unvalidated"
    },
    {
      "order": 2,
      "kind": "compose",
      "language": "yaml",
      "label": "Save the compose file as docker-compose.yml",
      "body": "volumes:\n  lago_postgres_data:\n  lago_redis_data:\n  lago_storage_data:\n\nx-postgres-image: &postgres-image\n  image: getlago/postgres-partman:15.0-alpine\nx-redis-image: &redis-image\n  image: redis:7-alpine\nx-backend-image: &backend-image\n  image: getlago/api:v1.55.0\nx-frontend-image: &frontend-image\n  image: getlago/front:v1.55.0\n\nx-lago-api-url: &lago-api-url\n  \"LAGO_API_URL\": ${LAGO_API_URL:-http://localhost:3000}\nx-lago-front-url: &lago-front-url\n  \"LAGO_FRONT_URL\": ${LAGO_FRONT_URL:-http://localhost}\n\nx-backend-environment: &backend-env\n  \"DATABASE_URL\": postgresql://${POSTGRES_USER:-lago}:${POSTGRES_PASSWORD:-changeme}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-lago}?search_path=${POSTGRES_SCHEMA:-public}\n  \"REDIS_URL\": redis://${REDIS_HOST:-redis}:${REDIS_PORT:-6379}\n  \"REDIS_PASSWORD\": ${REDIS_PASSWORD:-}\n  \"LAGO_REDIS_SIDEKIQ_SENTINELS\": ${LAGO_REDIS_SIDEKIQ_SENTINELS:-}\n  \"LAGO_REDIS_SIDEKIQ_MASTER_NAME\": ${LAGO_REDIS_SIDEKIQ_MASTER_NAME:-master}\n  \"LAGO_REDIS_SIDEKIQ_SENTINEL_USERNAME\": ${LAGO_REDIS_SIDEKIQ_SENTINEL_USERNAME:-}\n  \"LAGO_REDIS_SIDEKIQ_SENTINEL_PASSWORD\": ${LAGO_REDIS_SIDEKIQ_SENTINEL_PASSWORD:-}\n  \"SECRET_KEY_BASE\": ${SECRET_KEY_BASE:-your-secret-key-base-hex-64}\n  \"RAILS_ENV\": production\n  \"RAILS_LOG_TO_STDOUT\": ${LAGO_RAILS_STDOUT:-true}\n  \"LAGO_RSA_PRIVATE_KEY\": ${LAGO_RSA_PRIVATE_KEY}\n  \"LAGO_SIDEKIQ_WEB\": ${LAGO_SIDEKIQ_WEB:-true}\n  \"LAGO_ENCRYPTION_PRIMARY_KEY\": ${LAGO_ENCRYPTION_PRIMARY_KEY:-your-encryption-primary-key}\n  \"LAGO_ENCRYPTION_DETERMINISTIC_KEY\": ${LAGO_ENCRYPTION_DETERMINISTIC_KEY:-your-encryption-deterministic-key}\n  \"LAGO_ENCRYPTION_KEY_DERIVATION_SALT\": ${LAGO_ENCRYPTION_KEY_DERIVATION_SALT:-your-encryption-derivation-salt}\n  \"LAGO_USE_AWS_S3\": ${LAGO_USE_AWS_S3:-false}\n  \"LAGO_AWS_S3_ACCESS_KEY_ID\": ${LAGO_AWS_S3_ACCESS_KEY_ID:-azerty123456}\n  \"LAGO_AWS_S3_SECRET_ACCESS_KEY\": ${LAGO_AWS_S3_SECRET_ACCESS_KEY:-azerty123456}\n  \"LAGO_AWS_S3_REGION\": ${LAGO_AWS_S3_REGION:-us-east-1}\n  \"LAGO_AWS_S3_BUCKET\": ${LAGO_AWS_S3_BUCKET:-bucket}\n  \"LAGO_AWS_S3_ENDPOINT\": ${LAGO_AWS_S3_ENDPOINT}\n  \"LAGO_USE_GCS\": ${LAGO_USE_GCS:-false}\n  \"LAGO_GCS_PROJECT\": ${LAGO_GCS_PROJECT:-}\n  \"LAGO_GCS_BUCKET\": ${LAGO_GCS_BUCKET:-}\n  \"LAGO_FROM_EMAIL\": ${LAGO_FROM_EMAIL:-}\n  \"LAGO_SMTP_ADDRESS\": ${LAGO_SMTP_ADDRESS:-}\n  \"LAGO_SMTP_PORT\": ${LAGO_SMTP_PORT:-587}\n  \"LAGO_SMTP_USERNAME\": ${LAGO_SMTP_USERNAME:-}\n  \"LAGO_SMTP_PASSWORD\": ${LAGO_SMTP_PASSWORD:-}\n  \"LAGO_PDF_URL\": ${LAGO_PDF_URL:-http://pdf:3000}\n  \"LAGO_DATA_API_URL\": ${LAGO_DATA_API_URL:-http://data-api}\n  \"LAGO_DATA_API_BEARER_TOKEN\": ${LAGO_DATA_API_BEARER_TOKEN:-}\n  \"LAGO_REDIS_CACHE_URL\": redis://${LAGO_REDIS_CACHE_HOST:-redis}:${LAGO_REDIS_CACHE_PORT:-6379}\n  \"LAGO_REDIS_CACHE_PASSWORD\": ${LAGO_REDIS_CACHE_PASSWORD}\n  \"LAGO_REDIS_CACHE_SENTINELS\": ${LAGO_REDIS_CACHE_SENTINELS:-}\n  \"LAGO_REDIS_CACHE_MASTER_NAME\": ${LAGO_REDIS_CACHE_MASTER_NAME:-master}\n  \"LAGO_REDIS_CACHE_SENTINEL_USERNAME\": ${LAGO_REDIS_CACHE_SENTINEL_USERNAME:-}\n  \"LAGO_REDIS_CACHE_SENTINEL_PASSWORD\": ${LAGO_REDIS_CACHE_SENTINEL_PASSWORD:-}\n  \"LAGO_REDIS_CABLE_URL\": ${LAGO_REDIS_CABLE_URL:-}\n  \"LAGO_DISABLE_SEGMENT\": ${LAGO_DISABLE_SEGMENT}\n  \"LAGO_DISABLE_WALLET_REFRESH\": ${LAGO_DISABLE_WALLET_REFRESH}\n  \"LAGO_DISABLE_SIGNUP\": ${LAGO_DISABLE_SIGNUP:-false}\n  \"LAGO_WEBHOOK_ALLOW_PRIVATE_URLS\": ${LAGO_WEBHOOK_ALLOW_PRIVATE_URLS:-false}\n  \"LAGO_DISABLE_PDF_GENERATION\": ${LAGO_DISABLE_PDF_GENERATION:-false}\n  \"LAGO_OAUTH_PROXY_URL\": https://proxy.getlago.com\n  \"LAGO_LICENSE\": ${LAGO_LICENSE:-}\n  \"LAGO_CREATE_ORG\": ${LAGO_CREATE_ORG:-false}\n  \"LAGO_ORG_USER_PASSWORD\": ${LAGO_ORG_USER_PASSWORD:-}\n  \"LAGO_ORG_USER_EMAIL\": ${LAGO_ORG_USER_EMAIL:-}\n  \"LAGO_ORG_NAME\": ${LAGO_ORG_NAME:-}\n  \"LAGO_ORG_API_KEY\": ${LAGO_ORG_API_KEY:-}\n  \"GOOGLE_AUTH_CLIENT_ID\": ${GOOGLE_AUTH_CLIENT_ID:-}\n  \"GOOGLE_AUTH_CLIENT_SECRET\": ${GOOGLE_AUTH_CLIENT_SECRET:-}\n  \"MISTRAL_API_KEY\": ${MISTRAL_API_KEY:-}\n  \"MISTRAL_AGENT_ID\": ${MISTRAL_AGENT_ID:-}\n  # - SIDEKIQ_EVENTS=true\n  # - SIDEKIQ_PDFS=true\n  # - SIDEKIQ_BILLING=true\n  # - SIDEKIQ_CLOCK=true\n  # - SIDEKIQ_WEBHOOK=true\n  # - SIDEKIQ_AI_AGENT=true\n  # - SIDEKIQ_ALERTS=true\nx-frontend-environment: &frontend-env\n  \"API_URL\": ${LAGO_API_URL:-http://localhost:3000}\n  \"APP_ENV\": production\n  \"LAGO_OAUTH_PROXY_URL\": https://proxy.getlago.com\n  \"LAGO_DISABLE_PDF_GENERATION\": ${LAGO_DISABLE_PDF_GENERATION:-false}\n\nservices:\n  db:\n    <<: *postgres-image\n    container_name: lago-db\n    restart: unless-stopped\n    healthcheck:\n      test:\n        [\n          \"CMD-SHELL\",\n          \"pg_isready -U ${POSTGRES_USER:-lago} -d ${POSTGRES_DB:-lago} -h localhost -p ${POSTGRES_PORT:-5432}\",\n        ]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n    environment:\n      POSTGRES_DB: ${POSTGRES_DB:-lago}\n      POSTGRES_USER: ${POSTGRES_USER:-lago}\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}\n      PGDATA: /data/postgres\n      PGPORT: ${POSTGRES_PORT:-5432}\n      POSTGRES_SCHEMA: public\n    volumes:\n      - lago_postgres_data:/data/postgres\n    ports:\n      - ${POSTGRES_PORT:-5432}:${POSTGRES_PORT:-5432}\n\n  redis:\n    <<: *redis-image\n    container_name: lago-redis\n    restart: unless-stopped\n    healthcheck:\n      test: [\"CMD\", \"redis-cli\", \"-p\", \"${REDIS_PORT:-6379}\", \"ping\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n    command: --port ${REDIS_PORT:-6379}\n    volumes:\n      - lago_redis_data:/data\n    ports:\n      - ${REDIS_PORT:-6379}:${REDIS_PORT:-6379}\n\n  migrate:\n    <<: *backend-image\n    container_name: lago-migrate\n    depends_on:\n      db:\n        condition: service_healthy\n        restart: true\n    command: [\"./scripts/migrate.sh\"]\n    environment:\n      <<: *backend-env\n\n  api:\n    <<: *backend-image\n    container_name: lago-api\n    restart: unless-stopped\n    depends_on:\n      migrate:\n        condition: service_completed_successfully\n      db:\n        condition: service_healthy\n        restart: true\n      redis:\n        condition: service_healthy\n        restart: true\n    command: [\"./scripts/start.api.sh\"]\n    healthcheck:\n      test: curl -f http://localhost:3000/health || exit 1\n      interval: 10s\n      start_period: 30s\n      timeout: 60s\n      start_interval: 2s\n    environment:\n      <<: [*backend-env, *lago-api-url, *lago-front-url]\n    volumes:\n      - lago_storage_data:/app/storage\n    ports:\n      - ${API_PORT:-3000}:3000\n\n  front:\n    <<: *frontend-image\n    container_name: lago-front\n    restart: unless-stopped\n    # Use this command if you want to use SSL with Let's Encrypt\n    # command: \"/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \\\"daemon off;\\\"'\"\n    depends_on:\n      api:\n        condition: service_healthy\n        restart: true\n    environment:\n      <<: [*frontend-env, *lago-api-url, *lago-front-url]\n    ports:\n      - ${FRONT_PORT:-80}:80\n    #  - 443:443\n    # Using SSL with Let's Encrypt\n    # volumes:\n    #   - ./extra/nginx-letsencrypt.conf:/etc/nginx/conf.d/default.conf\n    #   - ./extra/certbot/conf:/etc/letsencrypt\n    #   - ./extra/certbot/www:/var/www/certbot\n    # Using SSL with self signed certificates\n    # volumes:\n    #   - ./extra/nginx-selfsigned.conf:/etc/nginx/conf.d/default.conf\n    #   - ./extra/ssl/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt\n    #   - ./extra/ssl/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key\n    #   - ./extra/ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem\n\n  # Only used for SSL support with Let's Encrypt\n  # certbot:\n  #   image: certbot/certbot\n  #   entrypoint: \"/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'\"\n  #   volumes:\n  #     - ./extra/certbot/conf:/etc/letsencrypt\n  #     - ./extra/certbot/www:/var/www/certbot\n\n  api-worker:\n    <<: *backend-image\n    container_name: lago-worker\n    restart: unless-stopped\n    depends_on:\n      migrate:\n        condition: service_completed_successfully\n      db:\n        condition: service_healthy\n        restart: true\n      redis:\n        condition: service_healthy\n        restart: true\n    command: [\"./scripts/start.worker.sh\"]\n    healthcheck:\n      test: curl -f http://localhost:8080 || exit 1\n      interval: 10s\n      start_period: 30s\n      timeout: 60s\n      start_interval: 2s\n    environment:\n      <<: [*backend-env, *lago-api-url]\n    volumes:\n      - lago_storage_data:/app/storage\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the event ingestion.\n  # It is recommendend if you have a high usage of events to not impact the other Sidekiq Jobs.\n  #api-events-worker:\n  #  <<: *backend-image\n  #  container_name: lago-events-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.events.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the usage monitoring & alerting jobs.\n  # It is recommended if you have a high usage of alerts to not impact the other Sidekiq Jobs.\n  # Set SIDEKIQ_ALERTS=true on the other workers so alerting jobs are routed to this worker.\n  #api-alerts-worker:\n  #  <<: *backend-image\n  #  container_name: lago-alerts-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.alerts.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices pdf creation.\n  # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs.\n  #api-pdfs-worker:\n  #  <<: *backend-image\n  #  container_name: lago-pdfs-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.pdfs.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the invoices creation.\n  # It is recommended if you have a high usage of invoices being created to not impact the other Sidekiq Jobs.\n  #api-billing-worker:\n  #  <<: *backend-image\n  #  container_name: lago-billing-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.billing.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the clock jobs.\n  #api-clock-worker:\n  #  <<: *backend-image\n  #  container_name: lago-clock-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.clock.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the webhook jobs.\n  #api-webhook-worker:\n  #  <<: *backend-image\n  #  container_name: lago-webhook-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.webhook.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the analytics-related jobs.\n  #api-analytics-worker:\n  #  <<: *backend-image\n  #  container_name: api-analytics-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.analytics.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  # You can uncomment this if you want to use a dedicated Sidekiq worker for the AI Agent-related jobs.\n  #api-ai-agent-worker:\n  #  <<: *backend-image\n  #  container_name: api-ai-agent-worker\n  #  restart: unless-stopped\n  #  depends_on:\n  #    api:\n  #      condition: service_healthy\n  #  command: [\"./scripts/start.ai_agent.worker.sh\"]\n  #  environment:\n  #    <<: [*backend-env, *lago-api-url]\n\n  api-clock:\n    <<: *backend-image\n    container_name: lago-clock\n    restart: unless-stopped\n    depends_on:\n      migrate:\n        condition: service_completed_successfully\n      db:\n        condition: service_healthy\n        restart: true\n      redis:\n        condition: service_healthy\n        restart: true\n    command: [\"./scripts/start.clock.sh\"]\n    environment:\n      <<: [*backend-env, *lago-api-url]\n\n  pdf:\n    image: getlago/lago-gotenberg:7.8.2\n",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "validation_status": "config_ok"
    },
    {
      "order": 3,
      "kind": "env",
      "language": "text",
      "label": "Set the values the compose file needs",
      "body": "These variables have no default in the compose file: LAGO_AWS_S3_ENDPOINT, LAGO_DISABLE_SEGMENT, LAGO_DISABLE_WALLET_REFRESH, LAGO_REDIS_CACHE_PASSWORD, LAGO_RSA_PRIVATE_KEY. Compose reads them from the shell or from a .env file next to the compose file. Replace the placeholder values listed under Gotchas.",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "validation_status": "unvalidated"
    },
    {
      "order": 4,
      "kind": "shell",
      "language": "bash",
      "label": "Start it",
      "body": "docker compose up -d",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "validation_status": "unvalidated"
    },
    {
      "order": 5,
      "kind": "verify",
      "language": "text",
      "label": "Open the app",
      "body": "Open http://localhost:80. The compose file publishes host port 80 for the front service.",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "validation_status": "unvalidated"
    }
  ],
  "notes": [
    {
      "kind": "gotcha",
      "title": "The compose file has placeholder values",
      "body": "Placeholder values: POSTGRES_PASSWORD is \"changeme\" (db), DATABASE_URL is \"changeme\" (migrate), DATABASE_URL is \"changeme\" (api), DATABASE_URL is \"changeme\" (api-worker), DATABASE_URL is \"changeme\" (api-clock).",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "checked_at": "2026-10-22"
    },
    {
      "kind": "gotcha",
      "title": "The compose file publishes host ports",
      "body": "Host ports: 5432 (db), 6379 (redis), 3000 (api), 80 (front). A port without a host address listens on all host network interfaces.",
      "source_url": "https://github.com/getlago/lago/blob/117b8219da7ad92631d47018ace3896f26201161/docker-compose.yml",
      "checked_at": "2026-10-22"
    }
  ],
  "signals": {
    "captured_at": "2026-10-22",
    "stars": 10705,
    "forks": 773,
    "open_issues": 33,
    "last_push": "2026-10-21",
    "days_since_push": 0,
    "latest_release": "v1.55.0",
    "latest_release_date": "2026-10-07",
    "days_since_release": 14
  },
  "links": {
    "html": "https://openlogs.fyi/tools/lago",
    "markdown": "https://openlogs.fyi/tools/lago.md",
    "json": "https://openlogs.fyi/tools/lago.json"
  },
  "updated_at": "2026-10-22"
}
