-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.example
More file actions
113 lines (101 loc) · 5.76 KB
/
Copy path.env.example
File metadata and controls
113 lines (101 loc) · 5.76 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
# Copy to .env and adjust. Used by docker-compose and local dev.
# Postgres (the compose `db` service is initialized with these)
# POSTGRES_PASSWORD is required — compose aborts while it is empty. Left blank on
# purpose: a shipped placeholder would satisfy that check and boot the stack on a
# password that is public in this repo.
POSTGRES_DB=app
POSTGRES_USER=app
POSTGRES_PASSWORD=
# better-auth — signs session cookies, so a known value here means anyone can
# forge any session. Left blank on purpose; generate your own and never reuse it:
# openssl rand -base64 32
# Must be >=32 chars of high entropy. The app refuses to start in production if
# it is shorter.
BETTER_AUTH_SECRET=
# Public base URL of the app. Behind an HTTPS reverse proxy this MUST be your
# public https:// URL — otherwise better-auth issues session cookies without the
# Secure flag and sign-in fails with INVALID_ORIGIN.
BETTER_AUTH_URL=http://localhost:3000
# Host port for the web container (container always listens on 3000)
WEB_PORT=3000
# Allow new account creation. Set to "false" to lock signup (e.g. after you've
# created your own account). Enforced server-side in better-auth on every method
# — both OAuth providers and email + password — not just in the UI.
ALLOW_SIGNUP=true
# Comma-separated emails that get the /admin panel (every account, its plan, its
# device usage, and a per-account device allowance for accounts with no
# subscription). Empty means nobody — the panel is off.
ADMIN_EMAILS=
# GitHub and Google OAuth apps. Both buttons are always offered, so all four are
# required even though email + password and username sign-in also exist.
# Create them at https://github.com/settings/developers and
# https://console.cloud.google.com/apis/credentials, with callback URLs:
# <BETTER_AUTH_URL>/api/auth/callback/github
# <BETTER_AUTH_URL>/api/auth/callback/google
# Left blank so compose stops at boot naming the missing one, rather than
# starting and failing at the first sign-in. Formats: GITHUB_CLIENT_ID Ov23...,
# GOOGLE_CLIENT_ID ....apps.googleusercontent.com.
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Resend, for the confirmation link a password sign-up needs before it gets a
# session. Required: without it a new account can be created but never entered.
# The key is at https://resend.com/api-keys (format re_...). MAIL_FROM must be a
# domain verified in that account; onboarding@resend.dev works unverified but
# only delivers to the address that owns the Resend account, so it is a local
# testing value, not a deployment one.
RESEND_API_KEY=
MAIL_FROM="UsageFleet <onboarding@resend.dev>"
# Reverse-proxy hops in front of the app, for rate-limit client-IP detection.
# false (default) — no trusted proxy: X-Forwarded-For is ignored (it's
# client-forgeable) and anonymous traffic shares one bucket. This also
# leaves the invalid-token throttle off, since no caller is attributable,
# and better-auth cannot name a caller either, so every sign-in shares one
# 3-per-10s bucket. Fine for a single-user homelab; on anything multi-user,
# front the app with a proxy and set both variables.
# true / a number — you run N trusted proxies (nginx/caddy/traefik) that strip
# inbound XFF and append a trustworthy entry; the IP is read that many hops
# from the right. Set this when behind a proxy so per-IP throttling works.
TRUST_PROXY=false
# The same promise, in the form better-auth wants: the addresses (IPs or CIDR
# ranges) of those proxies, comma-separated. better-auth resolves the client IP
# itself and cannot read a hop count. Empty, it trusts an X-Forwarded-For only
# when that header carries exactly ONE address; otherwise it cannot tell which
# entry is the real caller, gives up, and throttles every sign-in against one
# shared bucket at 3 per 10s — a deployment-wide login lockout.
#
# Set this on ANY proxied deployment, not just multi-hop ones. nginx's usual
# `proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for` APPENDS to
# whatever the client sent, so one unauthenticated request carrying its own
# X-Forwarded-For makes the header two entries long and trips the lockout on
# purpose. With this set, that forged entry is skipped and the real peer wins.
#
# List the addresses that appear INSIDE X-Forwarded-For, i.e. the outer hops;
# the proxy adjacent to the app never appears there. Keep the ranges tight: one
# broad enough to also cover your clients matches every entry in the chain and
# resolves to no IP at all. Malformed entries are dropped, so a typo reads as
# empty and the boot warning fires.
# TRUSTED_PROXIES=203.0.113.10
TRUSTED_PROXIES=
# Stripe billing. An account's device cap IS its plan (free = 1 device,
# Solo = 2, Fleet = 8), so all five are required in production — the app throws
# on boot without them. Create three recurring monthly prices in Stripe (one per
# paid plan) and paste their price ids here. Webhook endpoint:
# <BETTER_AUTH_URL>/api/auth/stripe/webhook
# subscribed to checkout.session.completed, customer.subscription.updated and
# customer.subscription.deleted.
# Left blank for the same reason as the OAuth pair above: a placeholder here
# satisfies compose's presence check and defers the failure to the first
# checkout. Formats: sk_..., whsec_..., price_....
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRICE_SOLO=
STRIPE_PRICE_FLEET=
# Unlike the two above, this one must be a per-unit price (suggested $0.35 per
# device / month): the device count is sent as the line-item
# quantity, so Stripe multiplies it. The actual amount is whatever you set on the
# price in Stripe — the app reads it back rather than hardcoding it.
STRIPE_PRICE_CUSTOM=
# For LOCAL (non-docker) dev only — points at a Postgres you run yourself:
# DATABASE_URL=postgresql://app:app@localhost:5432/app