-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
197 lines (185 loc) · 10.5 KB
/
Copy path.env.example
File metadata and controls
197 lines (185 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# Copy to `.env` and edit. Nothing here is required to run the app: with an
# empty file it boots fully public, reports nothing to the hub, and serves
# every documentation page. Each block below says what turns ON when you set
# it, and what the app does when you don't.
#
# `.env` is gitignored and excluded from the Docker image (.dockerignore) —
# a developer's copy was once baked into a production build, which killed the
# container at boot. Keep it that way.
#
# Values are read by `lib/backend.py`'s `load_dotenv()` at import time, which
# NEVER overrides a variable already in the environment. On Render, set these
# in the dashboard rather than committing a file.
# ---------------------------------------------------------------------------
# Backend
# ---------------------------------------------------------------------------
# flask | fastapi | quart. Flask is the default and the only one gunicorn can
# serve; the ASGI backends need `pip install "dash[fastapi]"` and uvicorn, so
# switching this alone is not enough — install the matching extra:
# pip install 'dash-improve-my-llms[fastapi]' (plus uvicorn)
# DASH_BACKEND=flask
# ---------------------------------------------------------------------------
# Canonical origin — THE value to get right
# ---------------------------------------------------------------------------
# Drives <link rel="canonical">, og:url, sitemap.xml, robots.txt and every
# absolute URL in llms.txt.
#
# THE FOOTGUN: this repo is the template every *.2plot.dev site is forked
# from. A fork that leaves this unset inherits
# `https://boilerplate.2plot.dev` and tells Google every one of its pages is a
# duplicate of THIS site. Traffic disappears and nothing looks broken, so
# `lib/constants.require_owned_base_url()` refuses to boot in production
# without it. Locally it is unset and the default is correct.
# APP_BASE_URL=https://boilerplate.2plot.dev
# ---------------------------------------------------------------------------
# Reverse proxy
# ---------------------------------------------------------------------------
# Trust `X-Forwarded-Proto` for the request scheme (lib/proxy.py). ON by
# default, which is correct behind Cloudflare/Render — they overwrite the
# header on every inbound request, so a client cannot forge it. Without it,
# Dash builds `twitter:url` from the last plaintext hop and every social
# scraper records `http://`. Set 0 ONLY if this app is exposed directly to the
# internet with no proxy in front.
# TRUST_PROXY_HEADERS=1
# ---------------------------------------------------------------------------
# Network bulletin (lib/bulletin.py)
# ---------------------------------------------------------------------------
# Hub-published tips and announcements, rendered in the header of the
# llms.txt viewer so a twenty-site network says "here is what changed" once.
# Unset -> the header still renders, using the package's built-in defaults and
# an "No announcements." empty state. There is no error either way, so check
# the boot log line "network bulletin: ..." to see which state you are in.
# NETWORK_BULLETIN_URL=https://2plot.dev/api/network/bulletin
# NETWORK_BULLETIN_TTL_S=900
# ---------------------------------------------------------------------------
# 2plot.ai satellite traffic reporting (lib/satellite_reporter.py)
# ---------------------------------------------------------------------------
# Without CROSS_APP_WEBHOOK_SECRET hits are still tracked locally, but nothing
# is POSTed to the hub and this app is absent from 2plot.ai/traffic. The same
# secret authenticates lib/hub_client.py's agent-key and page-tier calls.
# Get it from the 2plot.ai deployment config; never commit it.
# CROSS_APP_WEBHOOK_SECRET=
#
# This app's key in the hub's network directory. A fork MUST change it or its
# reports overwrite the boilerplate's rows, and it will receive the
# boilerplate's bulletin announcements — lib/bulletin.py reads the same value.
# SATELLITE_APP_KEY=boilerplate
# SATELLITE_TRAFFIC_URL=https://2plot.ai/api/satellite/traffic
# SATELLITE_REPORT_INTERVAL_S=3600
# SATELLITE_REPORT_DELAY_S=90
#
# Live "active now" presence beacon (POST /api/satellite/active, URL derived
# from SATELLITE_TRAFFIC_URL). Display-only and ephemeral hub-side; the
# rollup above stays the source of the daily numbers. 0 disables; floor 30s.
# SATELLITE_PRESENCE_INTERVAL_S=60
# SATELLITE_PRESENCE_URL=https://2plot.ai/api/satellite/active
# ---------------------------------------------------------------------------
# Interactive gate + machine-surface axis (lib/gate_layouts.py, lib/access.py)
# ---------------------------------------------------------------------------
# PAGE_DEFAULT_TIER is the per-host gate switch: `auth` shows anonymous
# browsers the sign-in card on every docs page whose frontmatter doesn't pin
# a tier. Funnel pages (/, /getting-started, /llms-small.txt, /llms-full.txt)
# are pinned public and never inherit it. Rollback = set back to public.
# PAGE_DEFAULT_TIER=public
#
# LLMS_PUBLIC_DEFAULT is the second axis and the later agent flip: while
# unset/1, machine surfaces (llms.txt family, crawler HTML, the prerender)
# stay open on auth-tier pages — the data-window posture. 0 gates anonymous
# machine fetches too; keyed agents still pass via the hub.
# LLMS_PUBLIC_DEFAULT=1
#
# /admin/control-board writes live per-page overrides (tier + llms_public)
# here — they win over frontmatter and the env defaults above, and apply on
# the next render with no restart. Point at a mounted disk in production or
# every toggle resets on deploy; the boot prints a [visibility] WARNING when
# this is unset or the path is not on a real mount.
# PAGE_VISIBILITY_FILE=/var/data/page_visibility.json
#
# Who may open the control board and read admin-tier pages. Comma-separated,
# case-insensitive; the OWNER_EMAIL code default always counts, so a deploy
# that set the Clerk keys but forgot this list still lets the owner in.
# ADMIN_EMAILS=you@example.com,colleague@example.com
# ADMIN_USER_IDS=user_2abc...
#
# Local-box escape hatch ONLY: opens /admin/control-board without Clerk.
# The board fails CLOSED by default because it can hide any page on the
# site. Never set in production.
# ALLOW_UNGATED_ADMIN=1
# ---------------------------------------------------------------------------
# Visitor analytics ledger (lib/analytics_tracker.py)
# ---------------------------------------------------------------------------
# Point at a mounted disk in production. On an ephemeral filesystem a mid-day
# deploy resets the ledger, and the next hourly report overwrites the hub's
# real total for today with whatever accumulated since the restart.
# TRAFFIC_ANALYTICS_FILE=/var/data/visitor_analytics.json
#
# Country comes from Cloudflare's CF-IPCountry header when present. The
# ip-api.com fallback is the only outbound call this app makes carrying a
# visitor IP, and it goes over plain HTTP — set 0 to disable it entirely.
# Behind Cloudflare it is redundant anyway.
# ANALYTICS_GEO_LOOKUP=0
# ANALYTICS_RETENTION_DAYS=45
# ANALYTICS_MAX_VISITS=20000
# ---------------------------------------------------------------------------
# 2plot.dev ad network (lib/ad_client.py)
# ---------------------------------------------------------------------------
# Both optional; defaults shown. If the ad server is unreachable the slot
# stays hidden and a 60s circuit breaker stops retrying, so an outage never
# adds a timeout to a page view.
# AD_SERVER_URL=https://2plot.dev
# AD_APP_ID=boilerplate
# ---------------------------------------------------------------------------
# Clerk authentication (lib/auth.py) — entirely optional
# ---------------------------------------------------------------------------
# With none of these set the site is fully public and non-public page tiers
# still deny (it fails CLOSED). Set all three of the first group to enable.
# The satellite settings matter: clerk-js derives the Frontend API from
# CLERK_SATELLITE_DOMAIN as `clerk.<domain>`, and Clerk only issues those DNS
# records per registered satellite domain — so this is `2plot.dev`, NOT the
# host this app is served on. See /reference/access.
# CLERK_SECRET_KEY=
# CLERK_PUBLISHABLE_KEY=
# CLERK_FRONTEND_API=https://clerk.2plot.ai
# CLERK_SIGN_IN_URL=https://accounts.2plot.ai/sign-in
# CLERK_SIGN_UP_URL=https://accounts.2plot.ai/sign-up
# CLERK_IS_SATELLITE=true
# CLERK_SATELLITE_DOMAIN=2plot.dev
#
# THE RETURN TRIP — required in production satellite mode, and the one Clerk
# setting that fails with no error anywhere. Set, the Sign In button
# navigates to `<value>?returnTo=<this page>` — a page on the hub's app that
# validates returnTo and sends the user home. Unset, sign-in falls back to
# the Clerk-hosted Account Portal, the hub's app never sees the request, and
# the user authenticates successfully and STAYS on 2plot.ai. A DESTINATION,
# not a flag: `true` or a bare host resolves against THIS site and 404s the
# button, which is worse than unset. lib/auth.py warns at boot for both
# mistakes. Leave unset locally (localhost is never a satellite).
# CLERK_SATELLITE_SIGN_IN_REDIRECT=https://2plot.ai/onboarding
# SESSION_SECRET=
# ---------------------------------------------------------------------------
# Corpus document tiers (lib/page_tiers.py; registered in run.py)
# ---------------------------------------------------------------------------
# Access tier for the tiered corpus documents served by dash-improve-my-llms
# >= 2.4.0: /llms-small.txt (compact briefing) and /llms-full.txt (every
# page's prose in one fetch). Values: public | auth | admin | hidden.
# Unset = public — the network's standing policy is that discovery documents
# stay free; these knobs exist so the 402 experiment can tighten the full
# corpus per-satellite without a redeploy of anything else. The hub's
# page-tier ceilings can also tighten either network-wide (a satellite can
# never loosen below the hub). Inert on older package versions.
# LLMS_SMALL_TIER=public
# LLMS_FULL_TIER=public
# ---------------------------------------------------------------------------
# Dash MCP server (Dash 4.3+)
# ---------------------------------------------------------------------------
# Off by default: a live introspection surface on a public host.
# DASH_MCP_ENABLED=0
# DASH_MCP_PATH=_mcp
# ---------------------------------------------------------------------------
# Development
# ---------------------------------------------------------------------------
# Downgrade the dependency-floor checks in run.py from fatal to warnings. Only
# for deliberately testing an older release — the floors exist because an IDE
# pointed at another project's virtualenv serves visibly older behaviour while
# looking completely healthy.
# ALLOW_STALE_DEPS=0