Skip to content

Commit adac53a

Browse files
committed
feat(trogon-gateway): consolidate sources into a single binary
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
1 parent 430b2db commit adac53a

65 files changed

Lines changed: 7755 additions & 897 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

devops/docker/compose/.env.example

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,56 @@
1+
# --- Gateway ---
2+
# TROGON_GATEWAY_PORT=8080
3+
14
# --- NATS ---
25
# NATS_URL=nats://localhost:4222
36

47
# --- GitHub Source ---
5-
# GITHUB_WEBHOOK_SECRET=
6-
# GITHUB_WEBHOOK_PORT=8080
7-
# GITHUB_SUBJECT_PREFIX=github
8-
# GITHUB_STREAM_NAME=GITHUB
9-
# GITHUB_STREAM_MAX_AGE_SECS=604800
10-
# GITHUB_NATS_ACK_TIMEOUT_SECS=10
11-
# GITHUB_MAX_BODY_SIZE=26214400
8+
# TROGON_SOURCE_GITHUB_WEBHOOK_SECRET=
9+
# TROGON_SOURCE_GITHUB_SUBJECT_PREFIX=github
10+
# TROGON_SOURCE_GITHUB_STREAM_NAME=GITHUB
11+
# TROGON_SOURCE_GITHUB_STREAM_MAX_AGE_SECS=604800
12+
# TROGON_SOURCE_GITHUB_NATS_ACK_TIMEOUT_SECS=10
13+
14+
# --- GitLab Source ---
15+
# TROGON_SOURCE_GITLAB_WEBHOOK_SECRET=
16+
# TROGON_SOURCE_GITLAB_SUBJECT_PREFIX=gitlab
17+
# TROGON_SOURCE_GITLAB_STREAM_NAME=GITLAB
18+
# TROGON_SOURCE_GITLAB_STREAM_MAX_AGE_SECS=604800
19+
# TROGON_SOURCE_GITLAB_NATS_ACK_TIMEOUT_SECS=10
1220

1321
# --- Linear Source ---
14-
# LINEAR_WEBHOOK_SECRET=
15-
# LINEAR_WEBHOOK_PORT=8080
16-
# LINEAR_SUBJECT_PREFIX=linear
17-
# LINEAR_STREAM_NAME=LINEAR
18-
# LINEAR_STREAM_MAX_AGE_SECS=604800
19-
# LINEAR_WEBHOOK_TIMESTAMP_TOLERANCE_SECS=60
20-
# LINEAR_NATS_ACK_TIMEOUT_MS=10000
22+
# TROGON_SOURCE_LINEAR_WEBHOOK_SECRET=
23+
# TROGON_SOURCE_LINEAR_SUBJECT_PREFIX=linear
24+
# TROGON_SOURCE_LINEAR_STREAM_NAME=LINEAR
25+
# TROGON_SOURCE_LINEAR_STREAM_MAX_AGE_SECS=604800
26+
# TROGON_SOURCE_LINEAR_NATS_ACK_TIMEOUT_SECS=10
27+
# TROGON_SOURCE_LINEAR_TIMESTAMP_TOLERANCE_SECS=60
28+
29+
# --- Discord Source ---
30+
# TROGON_SOURCE_DISCORD_MODE=gateway # "gateway" (WebSocket, all events) or "webhook" (HTTP, interactions only)
31+
# TROGON_SOURCE_DISCORD_BOT_TOKEN= # required when mode=gateway
32+
# TROGON_SOURCE_DISCORD_GATEWAY_INTENTS=guilds,guild_members,guild_messages,guild_message_reactions,direct_messages,message_content,guild_voice_states
33+
# TROGON_SOURCE_DISCORD_PUBLIC_KEY= # required when mode=webhook
34+
# TROGON_SOURCE_DISCORD_SUBJECT_PREFIX=discord
35+
# TROGON_SOURCE_DISCORD_STREAM_NAME=DISCORD
36+
# TROGON_SOURCE_DISCORD_STREAM_MAX_AGE_SECS=604800
37+
# TROGON_SOURCE_DISCORD_NATS_ACK_TIMEOUT_SECS=10
38+
# TROGON_SOURCE_DISCORD_NATS_REQUEST_TIMEOUT_SECS=2
39+
40+
# --- Telegram Source ---
41+
# TROGON_SOURCE_TELEGRAM_WEBHOOK_SECRET=
42+
# TROGON_SOURCE_TELEGRAM_SUBJECT_PREFIX=telegram
43+
# TROGON_SOURCE_TELEGRAM_STREAM_NAME=TELEGRAM
44+
# TROGON_SOURCE_TELEGRAM_STREAM_MAX_AGE_SECS=604800
45+
# TROGON_SOURCE_TELEGRAM_NATS_ACK_TIMEOUT_SECS=10
2146

2247
# --- Slack Source ---
23-
# SLACK_SIGNING_SECRET=
24-
# SLACK_WEBHOOK_PORT=3000
25-
# SLACK_SUBJECT_PREFIX=slack
26-
# SLACK_STREAM_NAME=SLACK
27-
# SLACK_STREAM_MAX_AGE_SECS=604800
28-
# SLACK_NATS_ACK_TIMEOUT_SECS=10
29-
# SLACK_MAX_BODY_SIZE=1048576
30-
# SLACK_TIMESTAMP_MAX_DRIFT_SECS=300
48+
# TROGON_SOURCE_SLACK_SIGNING_SECRET=
49+
# TROGON_SOURCE_SLACK_SUBJECT_PREFIX=slack
50+
# TROGON_SOURCE_SLACK_STREAM_NAME=SLACK
51+
# TROGON_SOURCE_SLACK_STREAM_MAX_AGE_SECS=604800
52+
# TROGON_SOURCE_SLACK_NATS_ACK_TIMEOUT_SECS=10
53+
# TROGON_SOURCE_SLACK_TIMESTAMP_MAX_DRIFT_SECS=300
3154

3255
# --- Logging ---
3356
# RUST_LOG=info

devops/docker/compose/compose.yml

Lines changed: 49 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -17,78 +17,63 @@ services:
1717
start_period: 5s
1818
retries: 3
1919

20-
trogon-source-github:
20+
trogon-gateway:
2121
build:
2222
context: ../../../rsworkspace
23-
dockerfile: ../devops/docker/compose/services/trogon-source-github/Dockerfile
23+
dockerfile: ../devops/docker/compose/services/trogon-gateway/Dockerfile
2424
environment:
2525
NATS_URL: "nats:4222"
26-
GITHUB_WEBHOOK_SECRET: "${GITHUB_WEBHOOK_SECRET:-}"
27-
GITHUB_WEBHOOK_PORT: "${GITHUB_WEBHOOK_PORT:-8080}"
28-
GITHUB_SUBJECT_PREFIX: "${GITHUB_SUBJECT_PREFIX:-github}"
29-
GITHUB_STREAM_NAME: "${GITHUB_STREAM_NAME:-GITHUB}"
30-
GITHUB_STREAM_MAX_AGE_SECS: "${GITHUB_STREAM_MAX_AGE_SECS:-604800}"
31-
GITHUB_NATS_ACK_TIMEOUT_SECS: "${GITHUB_NATS_ACK_TIMEOUT_SECS:-10}"
32-
GITHUB_MAX_BODY_SIZE: "${GITHUB_MAX_BODY_SIZE:-26214400}"
3326
RUST_LOG: "${RUST_LOG:-info}"
34-
depends_on:
35-
nats:
36-
condition: service_healthy
37-
restart: unless-stopped
38-
healthcheck:
39-
test: ["CMD", "curl", "-sf", "http://localhost:${GITHUB_WEBHOOK_PORT:-8080}/health"]
40-
interval: 10s
41-
timeout: 3s
42-
start_period: 10s
43-
retries: 3
27+
TROGON_GATEWAY_PORT: "${TROGON_GATEWAY_PORT:-8080}"
4428

45-
trogon-source-linear:
46-
build:
47-
context: ../../../rsworkspace
48-
dockerfile: ../devops/docker/compose/services/trogon-source-linear/Dockerfile
49-
environment:
50-
NATS_URL: "nats:4222"
51-
LINEAR_WEBHOOK_SECRET: "${LINEAR_WEBHOOK_SECRET}"
52-
LINEAR_WEBHOOK_PORT: "${LINEAR_WEBHOOK_PORT:-8080}"
53-
LINEAR_SUBJECT_PREFIX: "${LINEAR_SUBJECT_PREFIX:-linear}"
54-
LINEAR_STREAM_NAME: "${LINEAR_STREAM_NAME:-LINEAR}"
55-
LINEAR_STREAM_MAX_AGE_SECS: "${LINEAR_STREAM_MAX_AGE_SECS:-604800}"
56-
LINEAR_WEBHOOK_TIMESTAMP_TOLERANCE_SECS: "${LINEAR_WEBHOOK_TIMESTAMP_TOLERANCE_SECS:-60}"
57-
LINEAR_NATS_ACK_TIMEOUT_MS: "${LINEAR_NATS_ACK_TIMEOUT_MS:-10000}"
58-
RUST_LOG: "${RUST_LOG:-info}"
59-
depends_on:
60-
nats:
61-
condition: service_healthy
62-
restart: unless-stopped
63-
healthcheck:
64-
test: ["CMD", "curl", "-sf", "http://localhost:${LINEAR_WEBHOOK_PORT:-8080}/health"]
65-
interval: 10s
66-
timeout: 3s
67-
start_period: 10s
68-
retries: 3
29+
TROGON_SOURCE_GITHUB_WEBHOOK_SECRET: "${TROGON_SOURCE_GITHUB_WEBHOOK_SECRET:-}"
30+
TROGON_SOURCE_GITHUB_SUBJECT_PREFIX: "${TROGON_SOURCE_GITHUB_SUBJECT_PREFIX:-github}"
31+
TROGON_SOURCE_GITHUB_STREAM_NAME: "${TROGON_SOURCE_GITHUB_STREAM_NAME:-GITHUB}"
32+
TROGON_SOURCE_GITHUB_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_GITHUB_STREAM_MAX_AGE_SECS:-604800}"
33+
TROGON_SOURCE_GITHUB_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_GITHUB_NATS_ACK_TIMEOUT_SECS:-10}"
6934

70-
trogon-source-slack:
71-
build:
72-
context: ../../../rsworkspace
73-
dockerfile: ../devops/docker/compose/services/trogon-source-slack/Dockerfile
74-
environment:
75-
NATS_URL: "nats:4222"
76-
SLACK_SIGNING_SECRET: "${SLACK_SIGNING_SECRET:-}"
77-
SLACK_WEBHOOK_PORT: "${SLACK_WEBHOOK_PORT:-3000}"
78-
SLACK_SUBJECT_PREFIX: "${SLACK_SUBJECT_PREFIX:-slack}"
79-
SLACK_STREAM_NAME: "${SLACK_STREAM_NAME:-SLACK}"
80-
SLACK_STREAM_MAX_AGE_SECS: "${SLACK_STREAM_MAX_AGE_SECS:-604800}"
81-
SLACK_NATS_ACK_TIMEOUT_SECS: "${SLACK_NATS_ACK_TIMEOUT_SECS:-10}"
82-
SLACK_MAX_BODY_SIZE: "${SLACK_MAX_BODY_SIZE:-1048576}"
83-
SLACK_TIMESTAMP_MAX_DRIFT_SECS: "${SLACK_TIMESTAMP_MAX_DRIFT_SECS:-300}"
84-
RUST_LOG: "${RUST_LOG:-info}"
35+
TROGON_SOURCE_DISCORD_MODE: "${TROGON_SOURCE_DISCORD_MODE:-}"
36+
TROGON_SOURCE_DISCORD_BOT_TOKEN: "${TROGON_SOURCE_DISCORD_BOT_TOKEN:-}"
37+
TROGON_SOURCE_DISCORD_GATEWAY_INTENTS: "${TROGON_SOURCE_DISCORD_GATEWAY_INTENTS:-}"
38+
TROGON_SOURCE_DISCORD_PUBLIC_KEY: "${TROGON_SOURCE_DISCORD_PUBLIC_KEY:-}"
39+
TROGON_SOURCE_DISCORD_SUBJECT_PREFIX: "${TROGON_SOURCE_DISCORD_SUBJECT_PREFIX:-discord}"
40+
TROGON_SOURCE_DISCORD_STREAM_NAME: "${TROGON_SOURCE_DISCORD_STREAM_NAME:-DISCORD}"
41+
TROGON_SOURCE_DISCORD_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_DISCORD_STREAM_MAX_AGE_SECS:-604800}"
42+
TROGON_SOURCE_DISCORD_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_DISCORD_NATS_ACK_TIMEOUT_SECS:-10}"
43+
TROGON_SOURCE_DISCORD_NATS_REQUEST_TIMEOUT_SECS: "${TROGON_SOURCE_DISCORD_NATS_REQUEST_TIMEOUT_SECS:-2}"
44+
45+
TROGON_SOURCE_SLACK_SIGNING_SECRET: "${TROGON_SOURCE_SLACK_SIGNING_SECRET:-}"
46+
TROGON_SOURCE_SLACK_SUBJECT_PREFIX: "${TROGON_SOURCE_SLACK_SUBJECT_PREFIX:-slack}"
47+
TROGON_SOURCE_SLACK_STREAM_NAME: "${TROGON_SOURCE_SLACK_STREAM_NAME:-SLACK}"
48+
TROGON_SOURCE_SLACK_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_SLACK_STREAM_MAX_AGE_SECS:-604800}"
49+
TROGON_SOURCE_SLACK_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_SLACK_NATS_ACK_TIMEOUT_SECS:-10}"
50+
TROGON_SOURCE_SLACK_TIMESTAMP_MAX_DRIFT_SECS: "${TROGON_SOURCE_SLACK_TIMESTAMP_MAX_DRIFT_SECS:-300}"
51+
52+
TROGON_SOURCE_TELEGRAM_WEBHOOK_SECRET: "${TROGON_SOURCE_TELEGRAM_WEBHOOK_SECRET:-}"
53+
TROGON_SOURCE_TELEGRAM_SUBJECT_PREFIX: "${TROGON_SOURCE_TELEGRAM_SUBJECT_PREFIX:-telegram}"
54+
TROGON_SOURCE_TELEGRAM_STREAM_NAME: "${TROGON_SOURCE_TELEGRAM_STREAM_NAME:-TELEGRAM}"
55+
TROGON_SOURCE_TELEGRAM_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_TELEGRAM_STREAM_MAX_AGE_SECS:-604800}"
56+
TROGON_SOURCE_TELEGRAM_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_TELEGRAM_NATS_ACK_TIMEOUT_SECS:-10}"
57+
58+
TROGON_SOURCE_GITLAB_WEBHOOK_SECRET: "${TROGON_SOURCE_GITLAB_WEBHOOK_SECRET:-}"
59+
TROGON_SOURCE_GITLAB_SUBJECT_PREFIX: "${TROGON_SOURCE_GITLAB_SUBJECT_PREFIX:-gitlab}"
60+
TROGON_SOURCE_GITLAB_STREAM_NAME: "${TROGON_SOURCE_GITLAB_STREAM_NAME:-GITLAB}"
61+
TROGON_SOURCE_GITLAB_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_GITLAB_STREAM_MAX_AGE_SECS:-604800}"
62+
TROGON_SOURCE_GITLAB_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_GITLAB_NATS_ACK_TIMEOUT_SECS:-10}"
63+
64+
TROGON_SOURCE_LINEAR_WEBHOOK_SECRET: "${TROGON_SOURCE_LINEAR_WEBHOOK_SECRET:-}"
65+
TROGON_SOURCE_LINEAR_SUBJECT_PREFIX: "${TROGON_SOURCE_LINEAR_SUBJECT_PREFIX:-linear}"
66+
TROGON_SOURCE_LINEAR_STREAM_NAME: "${TROGON_SOURCE_LINEAR_STREAM_NAME:-LINEAR}"
67+
TROGON_SOURCE_LINEAR_STREAM_MAX_AGE_SECS: "${TROGON_SOURCE_LINEAR_STREAM_MAX_AGE_SECS:-604800}"
68+
TROGON_SOURCE_LINEAR_NATS_ACK_TIMEOUT_SECS: "${TROGON_SOURCE_LINEAR_NATS_ACK_TIMEOUT_SECS:-10}"
69+
TROGON_SOURCE_LINEAR_TIMESTAMP_TOLERANCE_SECS: "${TROGON_SOURCE_LINEAR_TIMESTAMP_TOLERANCE_SECS:-60}"
8570
depends_on:
8671
nats:
8772
condition: service_healthy
8873
restart: unless-stopped
8974
healthcheck:
90-
test: ["CMD", "curl", "-sf", "http://localhost:${SLACK_WEBHOOK_PORT:-3000}/health"]
91-
interval: 10s
75+
test: ["CMD", "curl", "-sf", "http://localhost:${TROGON_GATEWAY_PORT:-8080}/health"]
76+
interval: 5s
9277
timeout: 3s
9378
start_period: 10s
9479
retries: 3
@@ -97,33 +82,21 @@ services:
9782
image: ngrok/ngrok:alpine
9883
environment:
9984
NGROK_AUTHTOKEN: "${NGROK_AUTHTOKEN:-}"
100-
GITHUB_ADDR: "trogon-source-github:${GITHUB_WEBHOOK_PORT:-8080}"
101-
LINEAR_ADDR: "trogon-source-linear:${LINEAR_WEBHOOK_PORT:-8080}"
102-
SLACK_ADDR: "trogon-source-slack:${SLACK_WEBHOOK_PORT:-3000}"
85+
GATEWAY_ADDR: "trogon-gateway:${TROGON_GATEWAY_PORT:-8080}"
10386
entrypoint:
10487
- /bin/sh
10588
- -c
10689
- |
10790
cat > /tmp/ngrok.yml <<EOF
10891
version: 3
10992
tunnels:
110-
github:
111-
addr: $${GITHUB_ADDR}
112-
proto: http
113-
linear:
114-
addr: $${LINEAR_ADDR}
115-
proto: http
116-
slack:
117-
addr: $${SLACK_ADDR}
93+
gateway:
94+
addr: $${GATEWAY_ADDR}
11895
proto: http
11996
EOF
12097
exec ngrok start --all --config /tmp/ngrok.yml
12198
depends_on:
122-
trogon-source-github:
123-
condition: service_healthy
124-
trogon-source-linear:
125-
condition: service_healthy
126-
trogon-source-slack:
99+
trogon-gateway:
127100
condition: service_healthy
128101
restart: unless-stopped
129102
profiles:

devops/docker/compose/services/trogon-source-github/Dockerfile renamed to devops/docker/compose/services/trogon-gateway/Dockerfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ RUN cargo chef prepare --recipe-path recipe.json
1717
FROM chef AS builder
1818

1919
COPY --from=planner /build/recipe.json recipe.json
20-
RUN cargo chef cook --release --recipe-path recipe.json -p trogon-source-github
20+
RUN cargo chef cook --release --recipe-path recipe.json -p trogon-gateway
2121

2222
COPY Cargo.toml Cargo.lock ./
2323
COPY crates/ crates/
2424

25-
RUN cargo build --release -p trogon-source-github && \
26-
strip target/release/trogon-source-github
25+
RUN cargo build --release -p trogon-gateway && \
26+
strip target/release/trogon-gateway
2727

2828
# ── Stage 4: runtime ────────────────────────────────────────────────────────
2929
FROM debian:bookworm-20250317-slim AS runtime
@@ -34,12 +34,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
3434

3535
RUN useradd --no-create-home --shell /usr/sbin/nologin trogon
3636

37-
COPY --from=builder /build/target/release/trogon-source-github /usr/local/bin/trogon-source-github
37+
COPY --from=builder /build/target/release/trogon-gateway /usr/local/bin/trogon-gateway
3838

3939
USER trogon
4040

4141
EXPOSE 8080
4242

4343
STOPSIGNAL SIGTERM
4444

45-
ENTRYPOINT ["/usr/local/bin/trogon-source-github"]
45+
ENTRYPOINT ["/usr/local/bin/trogon-gateway", "serve"]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Receiving Source Events Locally
2+
3+
`trogon-gateway` is the unified inbound pipe for platform events into NATS
4+
JetStream. It runs all configured sources in a single process behind a single
5+
HTTP server.
6+
7+
All webhook sources share one port (default `8080`) and are routed by path
8+
prefix:
9+
10+
| Source | Webhook path | Required env var |
11+
|---|---|---|
12+
| GitHub | `/github/webhook` | `TROGON_SOURCE_GITHUB_WEBHOOK_SECRET` |
13+
| Discord | `/discord/webhook` | `TROGON_SOURCE_DISCORD_MODE` |
14+
| Slack | `/slack/webhook` | `TROGON_SOURCE_SLACK_SIGNING_SECRET` |
15+
| Telegram | `/telegram/webhook` | `TROGON_SOURCE_TELEGRAM_WEBHOOK_SECRET` |
16+
| GitLab | `/gitlab/webhook` | `TROGON_SOURCE_GITLAB_WEBHOOK_SECRET` |
17+
| Linear | `/linear/webhook` | `TROGON_SOURCE_LINEAR_WEBHOOK_SECRET` |
18+
19+
The gateway port is configured via `TROGON_GATEWAY_PORT` (default `8080`).
20+
A health endpoint is available at `GET /health`.
21+
22+
## Prerequisites
23+
24+
- Docker Compose
25+
- Credentials for the source(s) you want to enable
26+
- An [ngrok](https://ngrok.com) account (free tier, only for webhook sources
27+
that need a public URL)
28+
29+
## Quick start
30+
31+
Copy `.env.example` to `.env` and fill in the secrets for the sources you
32+
want:
33+
34+
```bash
35+
cp .env.example .env
36+
# edit .env — only set secrets for sources you want to run
37+
docker compose up
38+
```
39+
40+
## Discord modes
41+
42+
Discord supports two mutually exclusive modes via `TROGON_SOURCE_DISCORD_MODE`:
43+
44+
| Mode | Transport | Events | Requires |
45+
|---|---|---|---|
46+
| `gateway` | WebSocket (you connect to Discord) | Everything | `TROGON_SOURCE_DISCORD_BOT_TOKEN` |
47+
| `webhook` | HTTP POST (Discord connects to you) | Interactions only | `TROGON_SOURCE_DISCORD_PUBLIC_KEY` |
48+
49+
### Gateway mode
50+
51+
```bash
52+
TROGON_SOURCE_DISCORD_MODE=gateway \
53+
TROGON_SOURCE_DISCORD_BOT_TOKEN=<token> \
54+
docker compose up
55+
```
56+
57+
### Webhook mode
58+
59+
```bash
60+
TROGON_SOURCE_DISCORD_MODE=webhook \
61+
TROGON_SOURCE_DISCORD_PUBLIC_KEY=<hex-key> \
62+
docker compose --profile dev up
63+
```
64+
65+
Find the ngrok tunnel URL in `docker compose logs ngrok`, then set it as
66+
your Discord application's Interactions Endpoint URL (append `/discord/webhook`).
67+
68+
## Exposing webhooks with ngrok
69+
70+
```bash
71+
docker compose --profile dev up
72+
```
73+
74+
This starts ngrok alongside the gateway. Check `docker compose logs ngrok`
75+
for the public URL. Append the source prefix path when configuring each
76+
platform's webhook settings (e.g. `https://<ngrok-url>/github/webhook`).
77+
78+
## Verify
79+
80+
Subscribe to NATS to see events flowing:
81+
82+
```bash
83+
nats sub -s nats://nats.trogonai.orb.local:4222 ">"
84+
```
85+
86+
## Environment variables
87+
88+
See `.env.example` for the full list of configurable env vars per source.
89+
All env vars use the `TROGON_SOURCE_<SOURCE>_` prefix.

0 commit comments

Comments
 (0)