Lago Docker Compose 部署实战指南:本地、轻量与生产三种方案的完整配置详解
【免费下载链接】lagoOpen Source Metering and Usage Based Billing API ⭐️ Consumption tracking, Subscription management, Pricing iterations, Payment orchestration & Revenue analytics项目地址: https://gitcode.com/GitHub_Trending/la/lago
Lago 是一个开源的计量(Metering)与用量计费(Usage Based Billing)API 平台,支持消费追踪、订阅管理、定价迭代、支付编排与收入分析。本文以 deploy/README.md 为骨架,结合仓库中的 deploy.sh、docker-compose.local.yml、docker-compose.light.yml、docker-compose.production.yml 三份编排文件,系统讲解 Lago 的 Docker Compose 部署体系:如何在本机快速启动、如何借助 Traefik + Let's Encrypt 暴露公网 HTTPS 服务、如何拆分 Sidekiq Worker 应对生产负载,以及如何通过 Profile、外部数据库、RSA 密钥等手段灵活裁剪与加固部署。读完后你将具备从零搭建 Lago 全套计费服务并落地生产监控的完整能力。
一、部署方案总览:三种 Compose 编排的定位与差异
Lago 的deploy/目录为不同场景准备了三套 Docker Compose 编排文件,它们共享同一套服务模型(PostgreSQL + Redis + API + Front + Worker + Clock + PDF),差异主要体现在流量入口和 Worker 拆分粒度上:
| 编排文件 | 场景定位 | 反向代理 / TLS | 特色 |
|---|---|---|---|
| docker-compose.local.yml | 本地开发、小规模生产 | 无(直接暴露端口) | 依赖最少,docker compose up即可运行 |
| docker-compose.light.yml | 轻量生产 | Traefik v3 + Let's Encrypt | 单域名统一入口,自动签发 SSL 证书 |
| docker-compose.production.yml | 生产、高负载 | Traefik v3 + Let's Encrypt | 拆分 6 类 Worker 并行消费,内置 Portainer 管理面板 |
三份文件使用的镜像保持一致:后端为getlago/api:v1.27.1、前端为getlago/front:v1.27.1、PostgreSQL 为postgres:15-alpine、Redis 为redis:7-alpine,PDF 服务则统一使用getlago/lago-gotenberg:8.15(Gotenberg 转换服务,关闭 LibreOffice 路由、关闭 Chromium JavaScript、API 超时 300 秒)。
说明:本仓库根目录还有一份面向更高版本(
getlago/api:v1.52.0)的 docker-compose.yml,其中注释了 events / alerts / pdfs / billing / clock / webhook / analytics / ai-agent 等专用 Worker 的启用方法,可作为扩展部署的参考。
二、Docker Compose Local:五分钟跑起本地环境
Local 方案面向"快速体验 + 小规模生产"设计。README 明确提示:它可用于小规模生产用途,但不推荐用于大规模部署。
2.1 获取编排文件
官方流程通过 curl 拉取编排文件。在当前仓库中,该文件即 deploy/docker-compose.local.yml,可以直接从仓库复制,或使用仓库自带的 deploy/deploy.sh 一键脚本(见第六节)自动获取:
# 将仓库 deploy/docker-compose.local.yml 复制为工作目录下的 docker-compose.yml # (或直接使用仓库根目录的 docker-compose.yml)2.2 启动全部服务
Local 方案的默认端口为:API3000、前端80、PostgreSQL5432、Redis6379,全部通过环境变量可覆盖(API_PORT、FRONT_PORT、POSTGRES_PORT、REDIS_PORT)。
# 前台启动(便于观察日志) docker compose up --profile all # 后台启动 docker compose up -d --profile all2.3 服务组成与启动顺序
从 docker-compose.local.yml 可以看出,Local 方案包含 9 个服务,且存在严格的依赖链:
| 服务 | 容器名 | 启动脚本 / 职责 | 健康检查 |
|---|---|---|---|
db | lago-db | PostgreSQL 15,数据卷lago_postgres_data | pg_isready,10s 间隔、5 次重试 |
redis | lago-redis | Redis 7,数据卷lago_redis_data | redis-cli ping |
rsa-keys | lago-rsa-keys | 执行./scripts/generate.rsa.sh生成 JWT 密钥对 | 无 |
migrate | lago-migrate | 执行./scripts/migrate.sh执行数据库迁移,restart: no | 依赖 db 健康 |
api | lago-api | ./scripts/start.api.sh启动 Rails API,挂载存储卷 | curl -f http://localhost:3000/health |
front | lago-front | Nginx 托管前端 SPA | 依赖 api 健康 |
api-worker | lago-worker | ./scripts/start.worker.sh启动 Sidekiq Worker | curl -f http://localhost:8080 |
api-clock | lago-clock | ./scripts/start.clock.sh启动时钟/调度任务 | 无 |
pdf | — | Gotenberg PDF 生成服务 | 无 |
关键依赖关系如下,理解它有助于排障:
migrate等待db通过健康检查后才执行迁移;api依赖migrate成功完成(service_completed_successfully)、db与redis健康;api-worker、api-clock依赖migrate完成与db/redis健康;front依赖api健康。
2.4 核心后端环境变量(Local 默认值)
x-backend-environment锚点定义了后端服务的完整环境变量集,均可通过.env或 Shell 环境覆盖,这里列出最核心的几组:
- 数据库与缓存:
DATABASE_URL默认为postgresql://lago:changeme@db:5432/lago?search_path=public,REDIS_URL默认为redis://redis:6379; - 安全密钥:
SECRET_KEY_BASE(默认占位值your-secret-key-base-hex-64)、三个加密密钥LAGO_ENCRYPTION_PRIMARY_KEY/LAGO_ENCRYPTION_DETERMINISTIC_KEY/LAGO_ENCRYPTION_KEY_DERIVATION_SALT,以及 JWT 用的LAGO_RSA_PRIVATE_KEY; - 对外地址:
LAGO_API_URL默认http://localhost:3000,LAGO_FRONT_URL默认http://localhost; - 对象存储:
LAGO_USE_AWS_S3(默认false)与LAGO_USE_GCS(默认false),关闭时文件落在lago_storage_data卷的/app/storage; - 邮件:
LAGO_SMTP_ADDRESS/LAGO_SMTP_PORT(默认 587)/ 用户名 / 密码,以及发件人LAGO_FROM_EMAIL; - 功能开关:
LAGO_SIDEKIQ_WEB(默认true,暴露 Sidekiq Web 面板)、LAGO_DISABLE_SIGNUP(默认false)、LAGO_CREATE_ORG(默认false)。
三、Docker Compose Light:Traefik + Let's Encrypt 的 HTTPS 轻量部署
Light 方案在 Local 基础上引入Traefik v3.3 反向代理,统一以https://<LAGO_DOMAIN>对外提供服务,并由 Let's Encrypt 自动签发与续期 TLS 证书。
⚠️前提条件:必须拥有一个有效域名,且该域名已配置至少一条 A 或 AAAA 记录指向部署主机,否则 Let's Encrypt 的 TLS-ALPN 校验将无法完成。
3.1 获取文件与环境变量
# 仓库中对应文件为 deploy/docker-compose.light.yml 与 deploy/.env.light.example # 复制到工作目录后按需修改 .env.env.light.example 仅含两个必填项,这也是 Light 方案的全部必填配置:
LAGO_DOMAIN=domain.tld LAGO_ACME_EMAIL=email@domain.tldLAGO_ACME_EMAIL用于 Let's Encrypt 证书的注册与到期通知;LAGO_DOMAIN同时驱动 Traefik 路由规则和后端 URL 拼接(LAGO_FRONT_URL=https://${LAGO_DOMAIN}、LAGO_API_URL=https://${LAGO_DOMAIN}/api)。
3.2 启动
docker compose up --profile all # 后台运行 docker compose up -d --profile all3.3 Traefik 的路由设计(源码级解读)
从 docker-compose.light.yml 可以看到 Traefik 的完整配置,值得注意的细节:
- 入口:仅开放
websecure(443);通过--providers.docker.exposedbydefault=false禁止所有容器默认暴露,只有打了traefik.enable=true标签的服务才进入路由; - ACME:使用
tlschallenge=true,证书存储于./letsencrypt/acme.json;当前配置使用 Let's Encryptstaging 环境(caServer=https://acme-staging-v02.api.letsencrypt.org/directory),正式上线时应切换为生产端点https://acme-v02.api.letsencrypt.org/directory,否则浏览器会提示证书不受信任; - API 路由(
priority=100):Host(域名) && PathPrefix(/api/),并挂载stripprefix中间件剥掉/api前缀后转发到 API 容器 3000 端口; - 版本化 API 路由(
priority=110):PathPrefix(/api/v)拥有更高优先级,保证版本化接口不被前缀剥离规则干扰; - Rails 资源路由:
PathPrefix(/rails)转发到 API 容器(Sidekiq Web 等面板资源); - GraphQL 路由:
Path(/graphql)精确匹配转发; - 前端路由(
priority=50):Host(域名)兜底转发到 front 容器 80 端口。
这种"前端兜底 + API 按前缀分流"的设计,让用户只需记住一个域名即可同时访问管理后台(Front)、REST/GraphQL API 与运维面板。
四、Docker Compose Production:面向高负载的 Worker 拆分部署
Production 方案是 Light 的增强版。README 指出它"额外添加了多个服务以帮助处理更多负载,并内置 Portainer 用于扩缩容与栈管理"。
4.1 获取文件与环境变量
# 仓库中对应文件为 deploy/docker-compose.production.yml 与 deploy/.env.production.example.env.production.example 在 Light 基础上增加两个必填项:
LAGO_DOMAIN=domain.tld LAGO_ACME_EMAIL=email@domain.tld PORTAINER_USER=lago PORTAINER_PASSWORD=changeme4.2 启动
docker compose up --profile all # 后台运行 docker compose up -d --profile all4.3 六个专用 Worker 与并发配置
Production 与 Light 最大的区别在 Worker 层:Light 只有 1 个api-worker,而 Production 按职责拆分为 6 类独立进程(见 docker-compose.production.yml),每个 Worker 拥有独立的 Sidekiq 并发度与数据库连接池:
| 服务 | 容器名 | 启动脚本 | 默认并发(SIDEKIQ_CONCURRENCY / DATABASE_POOL) | 职责 |
|---|---|---|---|---|
worker | lago-worker | ./scripts/start.worker.sh | 20 / 20 | 通用任务 |
billing-worker | lago-billing-worker | ./scripts/start.billing.worker.sh | 5 / 5 | 计费与开票任务 |
pdf-worker | lago-pdf-worker | ./scripts/start.pdf.worker.sh | 5 / 5 | 发票 PDF 生成 |
webhook-worker | lago-webhook-worker | ./scripts/start.webhook.worker.sh | 10 / 10 | Webhook 投递 |
clock-worker | lago-clock-worker | ./scripts/start.clock.worker.sh | 20 / 20 | 定时调度任务 |
events-worker | lago-events-worker | ./scripts/start.events.worker.sh | 20 / 20 | 事件/用量数据消费 |
同时,clock服务在 Production 方案中保留,且所有 Worker 的健康检查统一为curl -f http://localhost:8080。这种"一队列一进程"的拓扑能有效隔离重负载队列(如事件消费)与延迟敏感队列(如计费),与 docs/monitoring.md 中列出的billing、clock、events、pdfs、webhook等 Sidekiq 队列一一对应。
4.4 内置 Portainer 管理面板
Production 方案额外启动portainer/portainer-ce,通过/portainer前缀路由暴露在 HTTPS 域名下(同样使用stripprefix中间件),管理员凭据由PORTAINER_USER/PORTAINER_PASSWORD注入,数据持久化在portainer_data卷。借助 Portainer 可以可视化扩缩容 Worker 实例、查看容器日志与资源占用。
五、进阶:一键部署脚本 deploy.sh
除手工复制 compose 文件外,仓库还提供了交互式部署脚本 deploy/deploy.sh,将"依赖检查 → 存量清理 → 模板选择 → 环境变量引导 → 启动"串成一条龙。其核心流程:
- 依赖检查:依次检查
docker与docker compose是否安装,缺失则提示安装; - 存量处理:检测到正在运行的
lago-quickstart容器或lago-local/lago-light/lago-production三个 Compose 项目时,询问是否停止、删除,甚至清空lago_rsa_data、lago_postgres_data、lago_redis_data、lago_storage_data数据卷; - 模板选择:提供 4 种部署模式——Quickstart(单容器
docker run -d --name lago-quickstart -p 3000:3000 -p 80:80 getlago/lago:latest)、Local、Light、Production; - DNS 校验:对 Light/Production 模式,使用
dig或nslookup校验LAGO_DOMAIN是否存在 A 记录,未解析时交互询问是否继续; - 外部依赖引导:交互式询问是否使用外部 PostgreSQL / Redis,并据此自动追加必填环境变量、自动选择
all-no-pg/all-no-redis/all-no-dbProfile; - 写入 .env:将缺失的
LAGO_DOMAIN、LAGO_ACME_EMAIL、PORTAINER_USER、PORTAINER_PASSWORD等变量逐一提示录入并写入.env; - 启动:按所选模板执行
docker compose --profile <profile> up -d。
六、Profile 机制:按需裁剪服务
三份 compose 文件中的每个服务都通过profiles字段归属不同 Profile。README 列出的核心 Profile 如下:
| Profile | 效果 |
|---|---|
all | 启用全部服务 |
all-no-pg | 不启用 PostgreSQL(使用外部数据库时) |
all-no-redis | 不启用 Redis(使用外部 Redis 时) |
all-no-keys | 不启用 RSA 密钥生成服务 |
all-no-db | 不启用 PostgreSQL 与 Redis(两处都外接时) |
从 compose 源码可以精确看到各 Profile 的成员关系:
db服务属于all、all-no-redis、all-no-keys(即all-no-pg下数据库不启动);redis服务属于all、all-no-pg、all-no-keys;rsa-keys服务属于all、all-no-pg、all-no-redis、all-no-db;api、migrate、front、worker、clock 等业务服务不属于任何显式 Profile(始终随默认集合启动)。
对应的常用启动命令:
# 全部服务 docker compose up --profile all # 不用内置 PostgreSQL(外接数据库) docker compose up --profile all-no-pg # 不用内置 Redis(外接 Redis) docker compose up --profile all-no-redis # 不用内置 PostgreSQL 和 Redis docker compose up --profile all-no-db # 不用 RSA 密钥生成服务(自行注入 LAGO_RSA_PRIVATE_KEY) docker compose up --profile all-no-keys # 不启用 PostgreSQL、Redis 与 RSA 密钥生成(无任何显式 Profile) docker compose up七、外接 PostgreSQL 与 Redis
当需要复用已有数据库基础设施时,可以停用内置容器并指向外部实例。
7.1 使用外部 PostgreSQL
- 设置以下环境变量(
POSTGRES_SCHEMA可选):
POSTGRES_USER=your_user POSTGRES_PASSWORD=your_password POSTGRES_DB=lago POSTGRES_HOST=your-db-host POSTGRES_PORT=5432 # POSTGRES_SCHEMA=public # 可选,非 public schema 时填写- 启动时不带 PostgreSQL:
docker compose up --profile all-no-pg这些变量会拼接到DATABASE_URL:postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?search_path=${POSTGRES_SCHEMA:-public}。注意migrate服务的depends_on对 db 使用required: false,因此外接数据库时迁移任务会直接对远程库执行。
7.2 使用外部 Redis
- 设置以下环境变量(
REDIS_PASSWORD可选):
REDIS_HOST=your-redis-host REDIS_PORT=6379 # REDIS_PASSWORD=your_password # 可选- 启动时不带 Redis:
docker compose up --profile all-no-redis此外还有一组独立的缓存通道变量:LAGO_REDIS_CACHE_URL(默认redis://redis:6379)、LAGO_REDIS_CACHE_PASSWORD与LAGO_REDIS_CABLE_URL,用于 Rails 缓存与 ActionCable 场景,可单独指向专用 Redis。
八、RSA 密钥:JWT 签名的核心安全配置
README 明确说明:这套 compose 文件会生成一对 RSA 密钥,用于 JWT Token 的签名。密钥由rsa-keys服务执行./scripts/generate.rsa.sh生成,保存在lago_rsa_data卷中,对应后端容器内的/app/config/keys目录。
几点必须注意:
- 所有后端服务共享同一把 RSA 密钥;README 特别警告:"所有后端服务使用相同的 RSA 密钥,如果未提供密钥它们会立即退出";
- 如果希望使用自己的密钥,操作步骤如下:
- 删除
lago_rsa_data卷; - 生成密钥并 Base64 编码:
- 删除
openssl genrsa 2048 | openssl base64 -A- 将输出导出为
LAGO_RSA_PRIVATE_KEY环境变量; - 使用
all-no-keysProfile 启动,跳过密钥生成服务:
docker compose up --profile all-no-keys与之配套的还有SECRET_KEY_BASE与三把加密密钥(LAGO_ENCRYPTION_PRIMARY_KEY、LAGO_ENCRYPTION_DETERMINISTIC_KEY、LAGO_ENCRYPTION_KEY_DERIVATION_SALT),生产环境务必全部替换为随机强值并妥善保管——密钥丢失或变更将导致历史数据无法解密、Token 无法校验。
九、生产监控:Sidekiq 指标与告警
对于生产部署,README 建议为 Sidekiq Worker 配置监控,完整方案见 docs/monitoring.md。其核心要点可概括为两层:
- 基础指标(OSS 与 Pro 均可用):Sidekiq Web UI 内置 Prometheus Exporter,在
:3000/prometheus/metrics暴露指标,包括全局指标(sidekiq_processed_jobs_total、sidekiq_failed_jobs_total、sidekiq_workers、sidekiq_enqueued_jobs、sidekiq_scheduled_jobs、sidekiq_retry_jobs、sidekiq_dead_jobs等)、按队列指标(sidekiq_queue_latency_seconds、sidekiq_queue_enqueued_jobs、sidekiq_queue_max_processing_time_seconds等)与按主机指标; - Sidekiq Pro 增强指标(需 Pro License):设置
LAGO_SIDEKIQ_STATSD_ENDPOINT=statsd-exporter:9125后,通过 Datadog StatsD 客户端上报lago_api_前缀的按 Job 指标(lago_api_jobs_count、lago_api_jobs_success、lago_api_jobs_failure、lago_api_jobs_perform等),再经 StatsD Exporter 转为 Prometheus 格式。
监控文档还提供了可直接落地的 Prometheus 告警规则(如sidekiq_queue_latency_seconds > 300判定的队列延迟告警、sidekiq_workers == 0判定的 Worker 宕机告警、失败率超过 5% 的高失败率告警)以及 Grafana Dashboard 的面板布局建议(概览、队列健康、Worker 健康、Job 性能、容量规划五个区块),配合上文 Production 方案的 Worker 拆分拓扑,即可构成一套完整的"部署 + 观测"闭环。
十、排障与最佳实践小结
- 首次启动顺序异常:先
docker compose logs migrate确认迁移是否因数据库连接失败而退出,api需要migrate以service_completed_successfully结束才会启动; - 健康检查失败:
api的健康检查是curl -f http://localhost:3000/health(start_period: 30s),Worker 则是:8080;若 API 反复重启,通常是数据库/Redis 未就绪或 RSA 密钥缺失; - HTTPS 证书问题:Light/Production 当前使用 Let's Encrypt staging 端点,正式环境务必切换
caServer到生产端点,并确认域名 A 记录解析正常; - 生产安全基线:替换全部默认密钥与口令(
changeme、your-secret-key-base-hex-64、三把加密密钥、PORTAINER_PASSWORD)、为对象存储与邮件 SMTP 配置真实凭据、按负载调整各 Worker 的SIDEKIQ_CONCURRENCY与DATABASE_POOL; - 横向扩展:Production 方案配合 Portainer 可对单个 Worker 服务进行副本扩容;若事件、告警、PDF、计费等队列负载极高,可参考根目录 docker-compose.yml 中注释的
api-events-worker、api-alerts-worker、api-pdfs-worker、api-billing-worker等专用 Worker 模板进一步拆分。
至此,你已经掌握 Lago 从本地快速体验、单域名 HTTPS 上线到生产级 Worker 拆分与监控的完整部署路径;如需深入 Worker 队列架构与资源规划,可继续阅读 docs/architecture.md 与 docs/monitoring.md。
【免费下载链接】lagoOpen Source Metering and Usage Based Billing API ⭐️ Consumption tracking, Subscription management, Pricing iterations, Payment orchestration & Revenue analytics项目地址: https://gitcode.com/GitHub_Trending/la/lago
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考