mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
docs(self-hosting): reconcile DATABASE_URL/POSTGRES_PASSWORD guidance with the compose contract
The bundled compose constructs DATABASE_URL inside the app service from POSTGRES_PASSWORD, so the getting-started 'edit CHANGE-ME' step was a no-op and .env.example's literal POSTGRES_PASSWORD collided with the quick-start's appended one. Comment both out in .env.example so the append pattern yields a single key, and rewrite step 2 to state compose derives the URL. Add a first-user note to close public registration on an internet-exposed host and to save the password (no-SMTP CLI reset). Refresh the stale onboarding step-2 source comment.
This commit is contained in:
1 parent
6ad2dc858a
commit
ced4e45272
3 files changed
+50
-22
No files matched your search
+17
-8
@@ -18,15 +18,24 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# Database
|
||||
# -----------------------------------------------------------------------------
|
||||
# When using docker-compose.yml: the app container reaches Postgres via the
|
||||
# service name "db", so the hostname is "db" — NOT "localhost".
|
||||
# When developing without Docker (`pnpm dev` against a host-installed Postgres):
|
||||
# change the hostname to "localhost" and adjust the credentials.
|
||||
DATABASE_URL="postgresql://healthlog:CHANGE-ME@db:5432/healthlog?schema=public"
|
||||
# Bundled docker-compose.yml path (the common case): you do NOT set DATABASE_URL
|
||||
# here. Compose CONSTRUCTS it inside the `app` service from POSTGRES_PASSWORD
|
||||
# (see docker-compose.yml — the `environment:` block wins over any value in this
|
||||
# file), so a DATABASE_URL line here is ignored for that stack. Set only
|
||||
# POSTGRES_PASSWORD below and compose wires the connection string for you.
|
||||
#
|
||||
# Bare-Node / custom-compose path (`pnpm dev` against a host Postgres, or your
|
||||
# own compose that does NOT derive DATABASE_URL): uncomment DATABASE_URL and set
|
||||
# it explicitly. Hostname is "db" on the bundled compose network, or
|
||||
# "localhost" for a host-installed Postgres.
|
||||
# DATABASE_URL="postgresql://healthlog:YOUR_PASSWORD@localhost:5432/healthlog?schema=public"
|
||||
|
||||
# Postgres password — used both by the db service AND by DATABASE_URL above.
|
||||
# Pick a strong random password, e.g. `openssl rand -hex 32`.
|
||||
POSTGRES_PASSWORD="CHANGE-ME"
|
||||
# Postgres password for the bundled `db` service — and the value compose splices
|
||||
# into DATABASE_URL. The quick-start appends a generated one:
|
||||
# echo "POSTGRES_PASSWORD=$(openssl rand -hex 32)" >> .env
|
||||
# Left commented here so that append does not create a duplicate key. Uncomment
|
||||
# and set it directly instead if you prefer to edit the file by hand.
|
||||
# POSTGRES_PASSWORD="generate-with-openssl-rand-hex-32"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
@@ -53,11 +53,14 @@ echo "API_TOKEN_HMAC_KEY=$(openssl rand -hex 32)" >> .env
|
||||
| `ENCRYPTION_KEY` | AES-256-GCM key for at-rest secrets (Withings tokens, AI provider keys, VAPID secrets) | Coordinated; see `docs/ops/encryption-key-rotation.md` |
|
||||
| `API_TOKEN_HMAC_KEY` | HMAC-SHA256 key for hashing Bearer API tokens before storage | Invalidates every issued `hlk_*` token |
|
||||
|
||||
Then open `.env` and confirm `DATABASE_URL` includes the password you
|
||||
just generated. The default template (`postgresql://healthlog:CHANGE-ME@db:5432/healthlog`)
|
||||
references the literal string `CHANGE-ME`; replace it with the value
|
||||
you put in `POSTGRES_PASSWORD`, or rewrite the URL to substitute
|
||||
explicitly.
|
||||
You do **not** edit `DATABASE_URL` on the bundled `docker-compose.yml`
|
||||
stack: compose constructs the connection string inside the `app`
|
||||
service from `${POSTGRES_PASSWORD}` (its `environment:` block overrides
|
||||
any `DATABASE_URL` in `.env`), so the `openssl` line above is the only
|
||||
password step. `DATABASE_URL` only matters if you run a **bare Node**
|
||||
process (`pnpm dev` against a host Postgres) or a **custom compose** that
|
||||
does not derive it — in that case uncomment and set `DATABASE_URL`
|
||||
explicitly in `.env` (see the commented example there).
|
||||
|
||||
## 3. Bring the stack up
|
||||
|
||||
@@ -92,6 +95,22 @@ After the first user lands, you can:
|
||||
- Open `/measurements` and add a weight or blood pressure to confirm
|
||||
the data path is wired end-to-end.
|
||||
|
||||
> **Close public registration if you expose the instance to the
|
||||
> internet.** Registration stays **open** after the first admin so you
|
||||
> can invite the rest of your household — but on a publicly reachable
|
||||
> host that means strangers can still sign up. Once everyone who needs
|
||||
> an account has one, turn it off in **`/admin` → registration toggle**
|
||||
> (or keep it open and hand out invite links instead). The admin
|
||||
> dashboard shows a reminder while registration is open and you are the
|
||||
> only user.
|
||||
|
||||
> **No email is configured out of the box** — a deliberate first-boot
|
||||
> simplicity win, but it also means password reset has no self-service
|
||||
> path until you set SMTP (see `docs/self-hosting/notifications.md`). If
|
||||
> you are the sole admin, **save your password in a manager now**: a
|
||||
> locked-out solo admin with no SMTP recovers only via the CLI script in
|
||||
> `docs/ops/password-reset.md`.
|
||||
|
||||
## 5. Point the instance at a public hostname
|
||||
|
||||
Local-only is fine for a single-user trial. For anything more — and
|
||||
|
||||
@@ -13,18 +13,16 @@ import { getServerTranslator } from "@/lib/i18n/server-translator";
|
||||
import { resolveServerLocale } from "@/lib/i18n/server-locale";
|
||||
|
||||
/**
|
||||
* v1.4.25 W14b — onboarding wizard step page (foundation scaffold).
|
||||
* Onboarding wizard step page.
|
||||
*
|
||||
* Routes:
|
||||
* /onboarding/0 welcome → carousel / value-prop intro
|
||||
* /onboarding/1 goals → "what do you want to track?"
|
||||
* /onboarding/2 source → Withings / Apple Health / manual cards
|
||||
* /onboarding/2 source → device/import source cards (see
|
||||
* source-card-grid.tsx for the shipped set)
|
||||
* /onboarding/3 baseline → first measurement or sync confirmation
|
||||
* /onboarding/4 done → success screen + return to dashboard
|
||||
*
|
||||
* This page ships the scaffold only — the step body is a placeholder
|
||||
* `<div>` that the W14b-Content agent replaces with real step UI.
|
||||
*
|
||||
* Step gating:
|
||||
* - Unauthenticated → `/auth/login` (the proxy also enforces this,
|
||||
* but the server-side check keeps the contract explicit).
|
||||
@@ -139,10 +137,12 @@ export default async function OnboardingStepPage({ params }: PageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// Source (step 2) — four-card grid. Manual is the implicit default;
|
||||
// Withings opens OAuth in a new tab; Apple Health is rendered as a
|
||||
// "coming with v1.5" announce card; Garmin is omitted per the
|
||||
// W14b-Content brief (not on the roadmap yet).
|
||||
// Source (step 2) — card grid. Manual is the implicit default; the
|
||||
// connectable sources (Apple Health, WHOOP, Oura, Polar, Nightscout,
|
||||
// Fitbit/Pixel via Google Health) live in `source-card-grid.tsx`'s
|
||||
// SOURCE_CARDS / MORE_SOURCES lists — refer to that component for the
|
||||
// current shipped set rather than duplicating it here. The selection
|
||||
// is non-binding: nothing here auto-configures a sync.
|
||||
if (requested === 2) {
|
||||
return (
|
||||
<OnboardingShell step={2} userLocale={user.locale ?? null}>
|
||||
|
||||
Reference in new issue
Block a user