Setup gate on immich/n8n/audiobookshelf/uptime-kuma (decision 46); mealie/wger/calibre-web after_install; romm/zipline stale notes; grafana R-708; wger R-712
gates / gates (push) Successful in 2s
gates / gates (push) Successful in 2s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,3 +1,21 @@
|
||||
## The setup gate on four apps; every hard-coded default replaced; stale notes; grafana; wger's sign-in (2026-09-29, `09` §3 decisions 45–46)
|
||||
|
||||
- **The setup gate (decision 46, controller ≥ 0.280.0):** `setup_gate: true` on **immich**, **n8n**, **audiobookshelf**
|
||||
(each with a `setup_done_probe:` measured to flip on 9202) and **uptime-kuma** (no HTTP status: the household's
|
||||
„Kész, beállítottam"). A fresh install is closed to everyone but the household until the first setup is done.
|
||||
- **mealie**, **wger**, **calibre-web**: a generated `ADMIN_PASSWORD` + `after_install:` through the app's own code
|
||||
(mealie's user repository; Django `set_password`; `cps.py -s` as `abc`). calibre-web's field is
|
||||
`generate: "password:24:special"` (its policy). mealie and wger pass the password as `sys.argv[1]`, never inside the
|
||||
code (a security review of the drill commit caught the first shape). Proven on 9202 on fresh installs: the default is
|
||||
refused, the generated one signs in, a wrong one is refused.
|
||||
- **wger — R-712:** behind traefik a browser's https Origin was refused with "CSRF verification failed" (nobody could
|
||||
sign in from a browser). `CSRF_TRUSTED_ORIGINS=https://${SUBDOMAIN}.${DOMAIN}` + `X_FORWARDED_PROTO_HEADER_SET=True`.
|
||||
- **romm, zipline:** the stale `default_creds` notes (a login that does not exist) are gone; first steps say to create
|
||||
the admin on the first visit.
|
||||
- **grafana — R-708:** `GF_SECURITY_ADMIN_PASSWORD=${…:?…}` — compose refuses to start without it; never `admin`.
|
||||
- `FIRST-ADMIN.md`: 5 fixed (every class-3 app), 4 gated, 30 open. README + REUSE: the gate convention and the
|
||||
argv rule. Copy freeze recaptured (diff = those apps' strings only).
|
||||
|
||||
## No app goes live with a login a stranger knows — first two apps; the audit (2026-09-28 evening, `09` §3 decision 45)
|
||||
|
||||
- **`FIRST-ADMIN.md`** (new): how each of the 53 apps gets its first admin — class, fix route, status, and whether each
|
||||
|
||||
+22
-15
@@ -5,32 +5,39 @@ app on the household's domain (`*.domain` through the tunnel). Where the box can
|
||||
generates one at install and shows it on the app page. Where it cannot, the app stays in the catalog, and the install
|
||||
dialog and the app page say what the default login is and to change it at once.
|
||||
|
||||
**Mechanisms (controller ≥ 0.279.0):**
|
||||
**Mechanisms (controller ≥ 0.279.0; the gate ≥ 0.280.0):**
|
||||
- `after_install:` in `.felhom.yml` — one command in the app's own container after a FRESH install, with generated
|
||||
deploy values filled in; `success:` marker required. Never after a restore or a kept-data load. (`internal/stacks/after_install.go`)
|
||||
- The page's default-login rule — `app_info.default_creds` is shown, with the sentence „Ez az alkalmazás egy ismert,
|
||||
közös jelszóval indul: %s. Telepítés után azonnal változtasd meg." / "This app starts with a known, shared password:
|
||||
%s. Change it right after the install.", while that login is in effect; hidden once `after_install` replaced it.
|
||||
(`internal/web/known_login.go`)
|
||||
- The setup gate (`09` §3 decision 46, controller ≥ 0.280.0) — `setup_gate: true` (+ optional `setup_done_probe:`): a
|
||||
fresh install of an open-first-run app is closed to everyone but the household until the app's own status says an
|
||||
admin exists, or the household presses „Kész, beállítottam". Spike and verdict:
|
||||
`felhom.eu/documentation/audits/login-gate-2026-09-29/B/B-VERDICT.md` (14 of 34 class-4 apps have a probe — 2
|
||||
measured, 12 upstream; 20 need the button). **It does not close OPEN SIGN-UP after the setup** (R-711).
|
||||
- „Megváltoztattam" / "I changed it" (controller ≥ 0.280.0, R-710) — the household's word under a known default login.
|
||||
|
||||
**Classes:** 1 generated by us at install · 2 set by the household in our dialog · 3 a hard-coded default · 4 an open
|
||||
first-run screen (the first visitor creates the admin) · 5 no login by design · 6 unknown.
|
||||
**Sources:** **M** = measured on a box (named) · **R** = read in this catalog · **U** = upstream, read or remembered,
|
||||
NOT measured. Every U must be measured before a fix is built on it.
|
||||
|
||||
**Status 2026-09-28:** 2 apps fixed (claper, bookstack). 37 apps of class 3/4 remain (3 of class 3, 34 of class 4) — they are the work of the next
|
||||
sessions (R-707). Until each is fixed, a class-3 app shows the sentence (its `default_creds` is in the catalog); a
|
||||
class-4 app has no default to show, so its risk is the window until the household opens it first.
|
||||
**Status 2026-09-29:** 5 fixed by a generated first password (bookstack, calibre-web, claper, mealie, wger — every
|
||||
class-3 app); 4 class-4 apps gated (immich, n8n, audiobookshelf, uptime-kuma). **30 class-4 apps remain open** — the
|
||||
next sessions gate them app by app (R-707): a probe measured on 9202 where the app has one, the button where it has
|
||||
none. Until an app is gated, its risk is the window until the household opens it first.
|
||||
|
||||
| app | class | how the first admin exists | fix route | status | source |
|
||||
|---|---|---|---|---|---|
|
||||
| actualbudget | 4 | first visitor sets the server password | (b) `POST /account/bootstrap` | open | R, harness fixture |
|
||||
| adventurelog | 4 | open sign-up | (a) `DJANGO_ADMIN_*` env; (b) `createsuperuser --noinput` | open | R; U (env) |
|
||||
| audiobookshelf | 4 | first visitor creates root | (b) `POST /init` | open | R, fixture |
|
||||
| **audiobookshelf** | 4 | first visitor creates root | **setup gate**, probe `GET /status` → `isInit` | **GATED** — catalog, 2026-09-29 | **M 9202**: as immich (the probe, read from upstream, measured: opened ~20 s after `POST /init`); its app's login 200 after |
|
||||
| bentopdf | 5 | browser-only PDF tool, no accounts | – | fine | R |
|
||||
| **bookstack** | 3 | `admin@admin.com / password` | (b) `artisan bookstack:create-admin --initial` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works; **M demo-hp**: default still works on the installed app (unchanged, page warns) |
|
||||
| calcom | 4 | first visitor becomes admin (`/api/auth/setup`) | (b) `POST /api/auth/setup`; (a) `NEXT_PUBLIC_DISABLE_SIGNUP` | open | **M 9202** (setup 200 once, then 400) |
|
||||
| calibre-web | 3 | `admin / admin123` | (b) `cps.py -p /config/app.db -s admin:<pw>` — **needs a password with a special character** (its policy), our generator has none | open — needs a controller generator | **M 9202** (default works; `-s` refused an alphanumeric one); **M demo-hp**: default works (page warns) |
|
||||
| **calibre-web** | 3 | `admin / admin123` | (b) `cps.py -p /config/app.db -s admin:<pw>` as `abc`; `generate: password:24:special` (controller ≥ 0.280.0) | **FIXED** — catalog, 2026-09-29 | **M 9202**: fresh install — default refused, generated signs in (302), wrong refused; **M demo-hp**: the installed app's password changed by the operator's ruling (Part A) |
|
||||
| **claper** | 3 (+ open sign-up) | seeds `admin@claper.co / claper` | (b) `bin/claper rpc … update_user_password` | **FIXED** — catalog, decision 45 | **M 9202**: default fails, generated works, a restore keeps it |
|
||||
| code-server | 1 | `PASSWORD` generated, applied every start | – | fine | R |
|
||||
| crafty-controller | 1 | `CRAFTY_PASSWORD` → default.json | – | fine | R |
|
||||
@@ -45,12 +52,12 @@ class-4 app has no default to show, so its risk is the window until the househol
|
||||
| home-assistant | 4 | onboarding | (b) `POST /api/onboarding/users` | open | R, fixture |
|
||||
| homebox | 4 | open registration | (b) register API; (a) disable registration after | open | U |
|
||||
| homepage | 5 | static start page | – | fine | R |
|
||||
| immich | 4 | first visitor admin sign-up | (b) `POST /api/auth/admin-sign-up` | open | U |
|
||||
| **immich** | 4 | first visitor admin sign-up | **setup gate**, probe `GET /api/server/config` → `isInitialized` | **GATED** — catalog, 2026-09-29 (decision 46) | **M 9202**: stranger 302→gate page / 401 during and after the install; household in 0.2 s; probe opened it 0–20 s after the sign-up; phone-app API (Bearer) 200 after (`felhom.eu/documentation/audits/login-gate-2026-09-29/C/`) |
|
||||
| jellyfin | 4 | startup wizard | (b) `/Startup/*` | open | U |
|
||||
| kimai | 1 | `ADMIN_PASSWORD` → `ADMINPASS` | – | fine | R |
|
||||
| komga | 4 | first visitor claims | (b) `POST /api/v1/claim` | open | U |
|
||||
| mealie | 3 | `changeme@example.com / MyPassword` | (b) login + users API | open | R; fixture (login works) |
|
||||
| n8n | 4 | owner setup | (b) `POST /rest/owner/setup` | open | R, fixture |
|
||||
| **mealie** | 3 | `changeme@example.com / MyPassword` | (b) its own user repository (`update_password`), password as `sys.argv[1]` | **FIXED** — catalog, 2026-09-29 | **M 9202**: fresh install — default 401, generated 200, wrong 401 (`felhom.eu/documentation/audits/login-gate-2026-09-29/D/`) |
|
||||
| **n8n** | 4 | owner setup | **setup gate**, probe `GET /rest/settings` → `data.userManagement.showSetupOnFirstLoad` = false | **GATED** — catalog, 2026-09-29 | **M 9202**: as immich; opened by the probe ~20 s after the owner setup |
|
||||
| navidrome | 4 | first user is admin | (a) `ND_DEVAUTOCREATEADMINPASSWORD`; (b) `/auth/createAdmin` | open | R, fixture; U (env) |
|
||||
| nextcloud | 1 | `NEXTCLOUD_ADMIN_PASSWORD` → auto-install | – | fine | R; **M** demo-hp 2026-09-28 |
|
||||
| onlyoffice | 5 | JWT-protected API, no login screen | – | fine | R |
|
||||
@@ -64,19 +71,19 @@ class-4 app has no default to show, so its risk is the window until the househol
|
||||
| radarr | 4 | first visitor sets auth | (b) `PUT /api/v3/config/host` with the apikey | open | U |
|
||||
| rallly | 4 | magic link to any e-mail | (a) `INITIAL_ADMIN_EMAIL` + `ALLOWED_EMAILS` | open | U |
|
||||
| recipe-importer | 4 | our own image, open until set | (c) now; our own code | open | R |
|
||||
| romm | 4 (catalog said 3) | catalog note `admin / admin` is **stale**: on demo-hp it answers 401 like a wrong password; a first unauthenticated `POST /api/users` created the user (harness) | (b) `POST /api/users` | open — **the page warns with a login that does not exist** | **M demo-hp** (401); fixture |
|
||||
| romm | 4 (catalog said 3) | first unauthenticated `POST /api/users` creates the user (harness); the stale `admin / admin` note is **removed** (2026-09-29) | (b) `POST /api/users`; or the setup gate | open | **M demo-hp** (401 for the old note); fixture |
|
||||
| seerr | 4 | setup wizard (needs a media server) | (c) | open | U |
|
||||
| sonarr | 4 | as radarr | (b) | open | U |
|
||||
| sparkyfitness | 4 | open registration | (a) `SPARKY_FITNESS_ADMIN_EMAIL` + disable sign-up | open | U |
|
||||
| tandoor | 4 | setup page while no users | (b) `createsuperuser --noinput` | open | R, fixture |
|
||||
| termix | 4 | first registered user is admin | (b) user-create API | open | U |
|
||||
| uptime-kuma | 4 | first visitor creates admin | (b) socket.io `setup` | open | U |
|
||||
| **uptime-kuma** | 4 | first visitor creates admin (socket.io `setup`) | **setup gate**, no HTTP probe → the household's „Kész, beállítottam" | **GATED** — catalog, 2026-09-29 | **M 9202**: gate held across a controller restart; the press opened it (second press 409). The proof pressed WITHOUT doing the socket.io setup — the press trusts the household |
|
||||
| vaultwarden | 1 | `ADMIN_TOKEN` generated; invite-only (R-512) | – | fine | R |
|
||||
| vikunja | 4 | open registration | (b) `vikunja user create`; (a) disable registration | open | R, fixture |
|
||||
| wanderer | 4 | `PUBLIC_DISABLE_SIGNUP=false` | (a) disable after first user | open | U |
|
||||
| wger | 3 | `admin / adminadmin` | (b) `manage.py shell -c` set_password | open | R |
|
||||
| **wger** | 3 | `admin / adminadmin` | (b) Django `set_password`, password as `sys.argv[1]` | **FIXED** — catalog, 2026-09-29; + R-712 (a browser's https Origin was refused by CSRF) | **M 9202**: fresh install — default refused, generated signs in (302), wrong refused, with the browser's https Origin |
|
||||
| wishlist | 4 | first sign-up is admin | (b) `POST /signup` | open | R, fixture |
|
||||
| zipline | 4 (catalog said 3) | catalog note `admin / zipline` looks **stale** (v4 sets up on first run) | (b) setup API (U) | open | R; audit logs |
|
||||
| zipline | 4 (catalog said 3) | v4 sets up on first run; the stale `admin / zipline` note is **removed** (2026-09-29) | (b) setup API (U); or the setup gate (probe `/api/setup` `firstSetup`, U) | open | R; audit logs |
|
||||
|
||||
**Counts (computed from the table):** class 1: 8 · class 2: 1 · class 3: 5 (bookstack, calibre-web, claper, mealie, wger;
|
||||
romm and zipline were listed as 3 and are 4) · class 4: 34 · class 5: 5. **Fixed: 2.** **Open: 37.** Fine: 14.
|
||||
**Counts (computed from the table, 2026-09-29):** class 1: 8 · class 2: 1 · class 3: 5 · class 4: 34 · class 5: 5.
|
||||
**Fixed: 5** (every class-3 app). **Gated: 4.** **Open: 30** (class 4). Fine: 14.
|
||||
|
||||
@@ -168,6 +168,29 @@ Never run after a restore or a kept-data load. Keep `app_info.default_creds`: th
|
||||
succeeded, and says "This app starts with a known, shared password…" while it is still in effect. Per-app status:
|
||||
`FIRST-ADMIN.md`.
|
||||
|
||||
**Never paste `${ADMIN_PASSWORD}` into program code** (a `python3 -c` string, a Django `shell -c`, an Elixir `rpc`
|
||||
string): a quote in a household-typed password breaks or changes the program. Pass it as its OWN argument
|
||||
(`["python3", "-c", "...sys.argv[1]...", "${ADMIN_PASSWORD}"]`, mealie and wger) or inside a plain argument
|
||||
(`--password=${ADMIN_PASSWORD}`, calibre-web's `admin:${ADMIN_PASSWORD}`). An app whose policy demands a special
|
||||
character uses `generate: "password:24:special"` (controller ≥ 0.280.0: a lower, an upper, a digit and one of
|
||||
`-_.!@#%+=`).
|
||||
|
||||
### The setup gate (`setup_gate`, controller ≥ 0.280.0)
|
||||
|
||||
An app whose FIRST VISITOR creates the admin is installed closed to everyone but the household (a browser signed in
|
||||
to the dashboard) until its first setup is done (`09` §3 decision 46):
|
||||
|
||||
```yaml
|
||||
setup_gate: true
|
||||
setup_done_probe: # optional — without it the household presses "Done, I set it up"
|
||||
url: http://n8n:5678/rest/settings # the app's own read-only status, on the docker network
|
||||
field: data.userManagement.showSetupOnFirstLoad # dotted JSON path
|
||||
done: "false" # its value once an admin exists, as text
|
||||
```
|
||||
|
||||
The url uses the app's `container_name` and its internal port. **Measure the probe on 9202 before and after the
|
||||
setup** (it must flip), and prove a stranger gets the gate page / 401 until then. Per-app status: `FIRST-ADMIN.md`.
|
||||
|
||||
### App-email mapping (`smtp_mapping`)
|
||||
|
||||
Apps that can send outbound email (password resets, invites, confirmations) get it through
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
# REPORT — 2026-09-28 evening: no app goes live with a login a stranger knows (decision 45) — the audit and the first two apps
|
||||
# REPORT — 2026-09-29: the setup gate on four apps; every hard-coded default replaced (decisions 45–46)
|
||||
|
||||
Architecture: `09-update-architecture.md` §3 decision 45 (new); `01-topology-and-trust.md` links the audit.
|
||||
Architecture: `09-update-architecture.md` §3 decisions 45–46; `01-topology-and-trust.md` §5. Controller 0.280.0.
|
||||
Evidence: `felhom.eu/documentation/audits/login-gate-2026-09-29/` (B spike, C gate live, D defaults live).
|
||||
|
||||
| app | before | route | proof (9202, fresh install, controller 0.279.0) | live |
|
||||
|---|---|---|---|---|
|
||||
| claper | seeds admin@claper.co / claper (measured: authenticates) | `bin/claper rpc` update_user_password | default fails · generated works · wrong fails · restore keeps it | `9dc8a05` |
|
||||
| bookstack | admin@admin.com / password (measured, also on demo-hp) | `artisan bookstack:create-admin --initial` | default fails · generated works · wrong fails | this commit |
|
||||
| calibre-web | admin / admin123 (measured, also on demo-hp) | `cps.py -s` refuses an alphanumeric password | — | open: needs a special-character generator |
|
||||
| app | change | proof on 9202 (drill catalog, fresh install, controller 0.280.0) |
|
||||
|---|---|---|
|
||||
| immich | setup gate, probe `isInitialized` | stranger: gate page / 401 during install and until setup; household in 0.2 s; probe opened it; phone-app API 200 after |
|
||||
| n8n | setup gate, probe `showSetupOnFirstLoad` | as immich; opened ~20 s after the owner setup |
|
||||
| audiobookshelf | setup gate, probe `/status isInit` | as immich; opened ~20 s after `POST /init` |
|
||||
| uptime-kuma | setup gate, the household's button | held across a controller restart; the press opened it; a second press 409 |
|
||||
| mealie | `after_install` (argv) | default 401, generated 200, wrong 401 |
|
||||
| wger | `after_install` (argv) + R-712 CSRF | default refused, generated signs in with a browser's https Origin, wrong refused |
|
||||
| calibre-web | `after_install`, `password:24:special` | default refused, generated signs in, wrong refused |
|
||||
| romm, zipline | stale `default_creds` removed | the page no longer names a login that does not exist |
|
||||
| grafana | R-708 `${…:?…}` | `docker compose config`: empty/unset refused (rc 1), set → rc 0 |
|
||||
|
||||
The full table: `FIRST-ADMIN.md`. Evidence: `felhom.eu/documentation/audits/logins-nvme-2026-09-28/B/`.
|
||||
Gates: the catalog pre-push gates; `check-copy-i18n.py --capture-freeze` (diff = only these apps' strings).
|
||||
Status: `FIRST-ADMIN.md` — 5 fixed, 4 gated, 30 open (R-707).
|
||||
|
||||
@@ -21,7 +21,8 @@ Templates are config; the few script helpers other scripts must REUSE, never re-
|
||||
| **The one canonical example app** | `templates/paperless-ngx/` (both files) | Multi-container (app + postgres + redis), HDD + userdata mounts, full deploy_fields spectrum (domain/subdomain/secret/password/text/path/select). Copy this structure for any new app. |
|
||||
| `.felhom.yml` required fields | `templates/paperless-ngx/.felhom.yml` | All 53 apps: `display_name`, `description` (Hungarian), `category`, `subdomain`, `slug`, `resources{mem_request, mem_limit, pi_compatible, needs_hdd}`, `deploy_fields`, `app_info{tagline, use_cases, first_steps, ...}`, `healthcheck`. Optional: `smtp_mapping` (email-capable apps), `open_path` (non-root landing page, e.g. ghost). |
|
||||
| deploy_fields conventions | `templates/paperless-ngx/.felhom.yml` (`deploy_fields:` block) | Every app starts with `DOMAIN` (type `domain`) + `SUBDOMAIN` (type `subdomain`, `locked_after_deploy: true`). Secrets: `type: secret` + `generate:` — dominant generators `password:24` (DB passwords) and `hex:32` (app secret keys); `password:16` for shown admin passwords (`type: password`). HDD apps add `HDD_PATH` (`type: path`, placeholder `/mnt/felhom-drives/hdd_1`, locked). Labels/descriptions in Hungarian. |
|
||||
| **Known default login → `after_install:`** (decision 45, controller ≥ 0.279.0) | `templates/bookstack/.felhom.yml` (`ADMIN_PASSWORD` field + `after_install:` block); `FIRST-ADMIN.md` for every app | An app that starts with a known admin login gets a generated `type: password` field (`generate: "password:24"`, `locked_after_deploy: true`) and ONE `after_install: {service, env: [ADMIN_PASSWORD], command: [...], success: "<marker the output must carry>"}` through the app's OWN CLI, run once after a FRESH install. Keep `app_info.default_creds` — the page hides it once the command succeeded and warns while it is in effect. **Prove on 9202 (drill catalog) before live: the default fails, the generated password works, a wrong one fails.** TRAPS: `success:` is required because a CLI can exit 0 on an error (claper's `rpc`); our generator is letters+digits only, so an app with a special-character password policy (calibre-web) needs a new generator first; a Hungarian first-steps change needs `check-copy-i18n.py --capture-freeze`. |
|
||||
| **Known default login → `after_install:`** (decision 45, controller ≥ 0.279.0) | `templates/bookstack/.felhom.yml` (`ADMIN_PASSWORD` field + `after_install:` block); `FIRST-ADMIN.md` for every app | An app that starts with a known admin login gets a generated `type: password` field (`generate: "password:24"`, `locked_after_deploy: true`) and ONE `after_install: {service, env: [ADMIN_PASSWORD], command: [...], success: "<marker the output must carry>"}` through the app's OWN CLI, run once after a FRESH install. Keep `app_info.default_creds` — the page hides it once the command succeeded and warns while it is in effect. **Prove on 9202 (drill catalog) before live: the default fails, the generated password works, a wrong one fails.** TRAPS: `success:` is required because a CLI can exit 0 on an error (claper's `rpc`); **pass the password as its own argument, never inside program code** (`sys.argv[1]` — mealie, wger; security review 2026-09-29); a special-character policy uses `generate: "password:24:special"` (controller ≥ 0.280.0, calibre-web); a Hungarian first-steps change needs `check-copy-i18n.py --capture-freeze`. |
|
||||
| **Open first-run screen → `setup_gate:`** (decision 46, controller ≥ 0.280.0) | `templates/n8n/.felhom.yml` (probe), `templates/uptime-kuma/.felhom.yml` (no probe → the household's button); `FIRST-ADMIN.md` | `setup_gate: true` + optional `setup_done_probe: {url: http://<container_name>:<port>/<path>, field: <dotted.json.path>, done: "<text>"}` | TRAPS: the probe must FLIP on the setup — measure it before and after on 9202; an app with open sign-up after setup (R-711) is not closed by the gate; `url` is read on the docker network, so it names the container, not the subdomain. |
|
||||
| Controller-side health probe | `templates/vaultwarden/.felhom.yml` (`healthcheck:` block) | `healthcheck.checks[]` with `type: http` (port only), `type: api` (port + `path` + `expect.status: 200`), or `type: tcp` (port only — mealie, crafty-controller). Prefer `api` with a real health path when the app has one. |
|
||||
| App lifecycle (`available`/`hidden`/`abandoned`) | `templates/plant-it/.felhom.yml` (`lifecycle:` block) | Optional top-level `lifecycle:` in `.felhom.yml`. Absent/empty ≡ `available`. `hidden` = not offered for new installs; `abandoned` = same, PLUS a permanent "Nem karbantartott" badge + notice on every box already running it. **Deployed instances keep full function in both states** — lifecycle governs what is OFFERED, never what runs; the controller refuses a deploy of a non-available template server-side (fail-closed, so a stale link or direct POST cannot install one). Unknown value → treated as `available` + one WARN, never a broken template. **Do NOT take an app out of circulation by deleting or moving its directory** — that orphans every customer already running it, which is what the 2026-07-21 `retired/` experiment got wrong. The resolvability gate skips non-available apps, so an abandoned app's dead image is not a standing red. |
|
||||
| **Catalog gates — THE entry point** | `scripts/catalog_gates.py` | **Run `python3 scripts/catalog_gates.py <app>` after ANY template change** (mandated in `CLAUDE.md`). Runs all four gates below in order — image-pins, image-resolvable, volume-persistence, engine-major (2026-09-13; git-history diff, hook-only until CI fetches deeper, R-452) — and exits **non-zero if any fails**; **2 (UNDETERMINED) is reported distinctly and is never a pass**, 1 (convicted) outranks 2 in the summary. Naming app(s) scopes the two gates that accept scoping, which is the normal after-a-change run; with no names the RUNTIME gate deploys every template, so that form is **scratch host only**. **Why a runner** (operator ruling 2026-08-02, R-161): the only gates in this project that ever get run are the ones with a single entry point named in a CLAUDE.md — `felhom.eu/scripts/site_gates.py` is run, R-29's three orphans are named nowhere and have stopped nothing. Controller-side enforcement was rejected because a load-time check reads only the file and a static audit reports the catalog clean **including papra** — it would pass on the very defect it exists to catch; CI was rejected for now (neither repo has any, no users yet). Adding a fourth gate here means adding it to `GATES` in this file — nothing else. |
|
||||
|
||||
+16
-14
@@ -126,9 +126,8 @@
|
||||
"calibre-web": {
|
||||
"app_info.default_creds": "admin / admin123",
|
||||
"app_info.first_steps[0]": "Nyisd meg a books.DOMAIN címet a böngészőben",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: admin / admin123",
|
||||
"app_info.first_steps[2]": "Változtasd meg azonnal a jelszót",
|
||||
"app_info.first_steps[3]": "Dobj egy könyvet a Fájlkezelőben (FileBrowser) az import/calibre mappába — automatikusan feldolgozza és a media/books könyvtárba helyezi",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: admin és a Beállítások oldalon látható első jelszó",
|
||||
"app_info.first_steps[2]": "Dobj egy könyvet a Fájlkezelőben (FileBrowser) az import/calibre mappába — automatikusan feldolgozza és a media/books könyvtárba helyezi",
|
||||
"app_info.prerequisites[0]": "Külső HDD szükséges az e-könyvek tárolásához",
|
||||
"app_info.prerequisites[1]": "x86 processzor szükséges (a CWA tartalmazza a Calibre binárist)",
|
||||
"app_info.prerequisites[2]": "Legalább 768 MB szabad RAM ajánlott",
|
||||
@@ -140,6 +139,8 @@
|
||||
"app_info.use_cases[4]": "KOReader szinkronizáció (olvasási pozíció, könyvjelzők)",
|
||||
"data_paths[calibre].label": "Beolvasandó e-könyvek",
|
||||
"data_paths[media/books].label": "E-könyvtár",
|
||||
"deploy_fields[ADMIN_PASSWORD].description": "Az első bejelentkezéshez: admin és ez a jelszó. Kell benne kis- és nagybetű, szám és egy különleges karakter.",
|
||||
"deploy_fields[ADMIN_PASSWORD].label": "Admin jelszó (admin)",
|
||||
"deploy_fields[DOMAIN].description": "A szerver domain neve",
|
||||
"deploy_fields[DOMAIN].label": "Domain",
|
||||
"deploy_fields[HDD_PATH].description": "A külső merevlemez elérési útja, ahol a Calibre könyvtár található",
|
||||
@@ -530,8 +531,8 @@
|
||||
"mealie": {
|
||||
"app_info.default_creds": "changeme@example.com / MyPassword",
|
||||
"app_info.first_steps[0]": "Nyisd meg a mealie.DOMAIN címet a böngészőben",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: changeme@example.com / MyPassword",
|
||||
"app_info.first_steps[2]": "Változtasd meg azonnal az email címet és jelszót",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: changeme@example.com és a Beállítások oldalon látható első jelszó",
|
||||
"app_info.first_steps[2]": "Változtasd meg az email címet a sajátodra",
|
||||
"app_info.first_steps[3]": "Importáld az első receptet egy weboldal URL beillesztésével",
|
||||
"app_info.first_steps[4]": "Próbáld ki az étkezés tervezőt",
|
||||
"app_info.tagline": "Receptkezelő és étkezés tervező a családnak",
|
||||
@@ -540,6 +541,8 @@
|
||||
"app_info.use_cases[2]": "Heti étkezés tervezés és bevásárlólista generálás",
|
||||
"app_info.use_cases[3]": "Receptek megosztása családtagokkal és barátokkal",
|
||||
"app_info.use_cases[4]": "Többnyelvű felület - magyar is elérhető",
|
||||
"deploy_fields[ADMIN_PASSWORD].description": "Az első bejelentkezéshez: changeme@example.com és ez a jelszó. Utána a profilodban módosítható.",
|
||||
"deploy_fields[ADMIN_PASSWORD].label": "Admin jelszó (changeme@example.com)",
|
||||
"deploy_fields[DOMAIN].description": "A szerver domain neve",
|
||||
"deploy_fields[DOMAIN].label": "Domain",
|
||||
"deploy_fields[SUBDOMAIN].description": "Az alkalmazás aldomainje",
|
||||
@@ -861,9 +864,8 @@
|
||||
"description": "Magyar receptoldalak importálása Mealie-be és Tandoor-ba"
|
||||
},
|
||||
"romm": {
|
||||
"app_info.default_creds": "admin / admin",
|
||||
"app_info.first_steps[0]": "Nyisd meg az arcade.DOMAIN címet a böngészőben",
|
||||
"app_info.first_steps[1]": "Jelentkezz be az alapértelmezett admin / admin fiókkal",
|
||||
"app_info.first_steps[1]": "Az első megnyitáskor hozd létre az admin fiókodat",
|
||||
"app_info.first_steps[2]": "Változtasd meg azonnal a jelszót a Settings menüben",
|
||||
"app_info.first_steps[3]": "Töltsd fel a ROM fájlokat a Fájlkezelőben (FileBrowser) a roms/ mappába, platform mappákba rendezve (pl. roms/gba/, roms/snes/)",
|
||||
"app_info.first_steps[4]": "Indíts egy Scan-t a bal oldali menüben a ROM-ok beolvasásához",
|
||||
@@ -1089,8 +1091,8 @@
|
||||
"wger": {
|
||||
"app_info.default_creds": "admin / adminadmin",
|
||||
"app_info.first_steps[0]": "Nyisd meg a fitness.DOMAIN címet a böngészőben",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: admin / adminadmin",
|
||||
"app_info.first_steps[2]": "Változtasd meg azonnal a jelszót",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: admin és a Beállítások oldalon látható első jelszó",
|
||||
"app_info.first_steps[2]": "Add meg az email címedet a beállításokban",
|
||||
"app_info.first_steps[3]": "Hozd létre az edzéstervedet",
|
||||
"app_info.first_steps[4]": "Kezdd el naplózni az edzéseidet",
|
||||
"app_info.tagline": "Edzésnapló - edzéstervek, haladás követés és testsúly napló",
|
||||
@@ -1099,6 +1101,8 @@
|
||||
"app_info.use_cases[2]": "Gyakorlatok adatbázisa képekkel és leírásokkal",
|
||||
"app_info.use_cases[3]": "Kalória és tápanyag követés",
|
||||
"app_info.use_cases[4]": "API támogatás fitnesz alkalmazás integrációkhoz",
|
||||
"deploy_fields[ADMIN_PASSWORD].description": "Az első bejelentkezéshez: admin és ez a jelszó. Utána a beállításokban módosítható.",
|
||||
"deploy_fields[ADMIN_PASSWORD].label": "Admin jelszó (admin)",
|
||||
"deploy_fields[DOMAIN].description": "A szerver domain neve",
|
||||
"deploy_fields[DOMAIN].label": "Domain",
|
||||
"deploy_fields[SECRET_KEY].label": "Titkosítási kulcs",
|
||||
@@ -1124,12 +1128,10 @@
|
||||
"description": "Családi kívánságlista megosztás"
|
||||
},
|
||||
"zipline": {
|
||||
"app_info.default_creds": "admin / zipline",
|
||||
"app_info.first_steps[0]": "Nyisd meg az img.DOMAIN címet a böngészőben",
|
||||
"app_info.first_steps[1]": "Jelentkezz be: admin / zipline",
|
||||
"app_info.first_steps[2]": "Változtasd meg azonnal a jelszót",
|
||||
"app_info.first_steps[3]": "Konfiguráld a ShareX-et vagy Flameshot-ot az API URL-lel",
|
||||
"app_info.first_steps[4]": "Tölts fel egy screenshot-ot a teszteléshez",
|
||||
"app_info.first_steps[1]": "Az első megnyitáskor hozd létre az admin fiókodat",
|
||||
"app_info.first_steps[2]": "Konfiguráld a ShareX-et vagy Flameshot-ot az API URL-lel",
|
||||
"app_info.first_steps[3]": "Tölts fel egy screenshot-ot a teszteléshez",
|
||||
"app_info.prerequisites[0]": "ShareX (Windows) vagy Flameshot (Linux) ajánlott a screenshot feltöltéshez",
|
||||
"app_info.tagline": "Screenshot és fájlmegosztó szerver ShareX/Flameshot integrációval",
|
||||
"app_info.use_cases[0]": "Screenshotok automatikus feltöltése ShareX/Flameshot-ból",
|
||||
|
||||
@@ -53,6 +53,17 @@ deploy_fields:
|
||||
description: "A külső merevlemez elérési útja"
|
||||
locked_after_deploy: true
|
||||
|
||||
|
||||
# --- The setup gate (controller >= 0.280.0, `09` §3 decision 46) ---
|
||||
# The first visitor would create the admin. So a fresh install is closed to everyone but the household (a browser
|
||||
# signed in to the dashboard) until the first setup is done; audiobookshelf's own status says so (`/status` isInit — upstream, measured on 9202 by the
|
||||
# 2026-09-29 live proof).
|
||||
setup_gate: true
|
||||
setup_done_probe:
|
||||
url: http://audiobookshelf:80/status
|
||||
field: isInit
|
||||
done: "true"
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Hangoskönyv és podcast kezelő, lejátszó és szinkronizáló"
|
||||
|
||||
@@ -63,6 +63,16 @@ deploy_fields:
|
||||
description: "A külső merevlemez elérési útja, ahol a Calibre könyvtár található"
|
||||
locked_after_deploy: true
|
||||
|
||||
# `09` §3 decision 45: Calibre-Web starts with admin / admin123. The box replaces that password with this
|
||||
# generated one right after the install (after_install below). Its password policy demands a special character,
|
||||
# hence `:special` (controller >= 0.280.0).
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: "Admin jelszó (admin)"
|
||||
type: password
|
||||
generate: "password:24:special"
|
||||
description: "Az első bejelentkezéshez: admin és ez a jelszó. Kell benne kis- és nagybetű, szám és egy különleges karakter."
|
||||
locked_after_deploy: true
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: 'Automatizált e-könyv könyvtár - könyvfeldolgozás, formátumkonverzió és OPDS feed'
|
||||
@@ -78,8 +88,7 @@ app_info:
|
||||
|
||||
first_steps:
|
||||
- 'Nyisd meg a books.DOMAIN címet a böngészőben'
|
||||
- 'Jelentkezz be: admin / admin123'
|
||||
- 'Változtasd meg azonnal a jelszót'
|
||||
- 'Jelentkezz be: admin és a Beállítások oldalon látható első jelszó'
|
||||
- 'Dobj egy könyvet a Fájlkezelőben (FileBrowser) az import/calibre mappába — automatikusan feldolgozza és a media/books könyvtárba helyezi'
|
||||
|
||||
prerequisites:
|
||||
@@ -87,6 +96,16 @@ app_info:
|
||||
- 'x86 processzor szükséges (a CWA tartalmazza a Calibre binárist)'
|
||||
- 'Legalább 768 MB szabad RAM ajánlott'
|
||||
|
||||
# --- After a fresh install (controller >= 0.280.0, decision 45) ---
|
||||
# Calibre-Web's OWN `cps.py -s user:password`, as the app user. Measured on 9202 2026-09-29: afterwards admin123 no
|
||||
# longer signs in, the new one does; a password without a special character is refused by its policy.
|
||||
after_install:
|
||||
service: calibre-web
|
||||
user: abc
|
||||
env: [ADMIN_PASSWORD]
|
||||
command: ["python3", "/app/calibre-web-automated/cps.py", "-p", "/config/app.db", "-s", "admin:${ADMIN_PASSWORD}"]
|
||||
success: "Password for user 'admin' changed"
|
||||
|
||||
# --- Controller-side health probe ---
|
||||
healthcheck:
|
||||
checks:
|
||||
@@ -110,8 +129,7 @@ i18n:
|
||||
- 'KOReader sync (reading position, bookmarks)'
|
||||
first_steps:
|
||||
- 'Open books.DOMAIN in your browser'
|
||||
- 'Sign in: admin / admin123'
|
||||
- 'Change the password straight away'
|
||||
- 'Sign in: admin and the first password shown on the settings page'
|
||||
- 'Drop a book into the import/calibre folder in the File manager (FileBrowser) - it is processed and filed under media/books on its own'
|
||||
prerequisites:
|
||||
- 'An external hard drive is needed to keep the e-books on'
|
||||
@@ -128,6 +146,9 @@ i18n:
|
||||
label: 'E-book library path'
|
||||
description: 'The path to the external hard drive where the Calibre library lives'
|
||||
placeholder: '/mnt/felhom-drives/hdd_1'
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: 'Admin password (admin)'
|
||||
description: 'For the first sign-in: admin and this password. It needs a lower and an upper case letter, a digit and a special character.'
|
||||
data_paths:
|
||||
- path: 'calibre'
|
||||
label: 'E-books to read in'
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
environment:
|
||||
- TZ=Europe/Budapest
|
||||
- GF_SERVER_ROOT_URL=https://${SUBDOMAIN}.${DOMAIN}
|
||||
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD:-admin}
|
||||
- GF_SECURITY_ADMIN_PASSWORD=${GF_SECURITY_ADMIN_PASSWORD:?the admin password is required (R-708)}
|
||||
volumes:
|
||||
- grafana_data:/var/lib/grafana
|
||||
networks:
|
||||
|
||||
@@ -63,6 +63,17 @@ deploy_fields:
|
||||
description: "A külső merevlemez elérési útja, ahol a fotók és videók tárolódnak"
|
||||
locked_after_deploy: true
|
||||
|
||||
|
||||
# --- The setup gate (controller >= 0.280.0, `09` §3 decision 46) ---
|
||||
# The first visitor would create the admin. So a fresh install is closed to everyone but the household (a browser
|
||||
# signed in to the dashboard) until the first setup is done; immich's own status says so (measured on 9202 2026-09-29:
|
||||
# isInitialized false -> true once the admin exists).
|
||||
setup_gate: true
|
||||
setup_done_probe:
|
||||
url: http://immich-server:2283/api/server/config
|
||||
field: isInitialized
|
||||
done: "true"
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: 'Google Photos alternatíva - automatikus fotó mentés és rendszerezés'
|
||||
|
||||
@@ -40,6 +40,15 @@ deploy_fields:
|
||||
locked_after_deploy: true
|
||||
description: "Az alkalmazás aldomainje"
|
||||
|
||||
# `09` §3 decision 45: Mealie starts with changeme@example.com / MyPassword. The box replaces that password with
|
||||
# this generated one right after the install (after_install below); the app page shows it as the first password.
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: "Admin jelszó (changeme@example.com)"
|
||||
type: password
|
||||
generate: "password:24"
|
||||
description: "Az első bejelentkezéshez: changeme@example.com és ez a jelszó. Utána a profilodban módosítható."
|
||||
locked_after_deploy: true
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: 'Receptkezelő és étkezés tervező a családnak'
|
||||
@@ -55,11 +64,22 @@ app_info:
|
||||
|
||||
first_steps:
|
||||
- 'Nyisd meg a mealie.DOMAIN címet a böngészőben'
|
||||
- 'Jelentkezz be: changeme@example.com / MyPassword'
|
||||
- 'Változtasd meg azonnal az email címet és jelszót'
|
||||
- 'Jelentkezz be: changeme@example.com és a Beállítások oldalon látható első jelszó'
|
||||
- 'Változtasd meg az email címet a sajátodra'
|
||||
- 'Importáld az első receptet egy weboldal URL beillesztésével'
|
||||
- 'Próbáld ki az étkezés tervezőt'
|
||||
|
||||
# --- After a fresh install (controller >= 0.279.0, decision 45) ---
|
||||
# Mealie's OWN user repository sets the seeded user's password (what its scripts/change_password.py does, without the
|
||||
# prompts). Measured on 9202 2026-09-29: afterwards MyPassword answers 401 at /api/auth/token, the new one 200.
|
||||
after_install:
|
||||
service: mealie
|
||||
env: [ADMIN_PASSWORD]
|
||||
# The password is the LAST ARGUMENT (sys.argv[1]), never pasted into the code: a quote in it cannot break or change
|
||||
# the program (security review 2026-09-29).
|
||||
command: ["python3", "-c", "import sys\nfrom mealie.core.security.security import hash_password\nfrom mealie.db.db_setup import session_context\nfrom mealie.repos.repository_factory import AllRepositories\nwith session_context() as s:\n r = AllRepositories(s, group_id=None, household_id=None)\n u = r.users.get_one('changeme@example.com', 'email')\n r.users.update_password(u.id, hash_password(sys.argv[1]))\n print('FELHOM_AFTER_INSTALL_OK')\n", "${ADMIN_PASSWORD}"]
|
||||
success: "FELHOM_AFTER_INSTALL_OK"
|
||||
|
||||
# --- Controller-side health probe ---
|
||||
healthcheck:
|
||||
checks:
|
||||
@@ -98,8 +118,8 @@ i18n:
|
||||
- 'A multilingual interface - English and Hungarian among them'
|
||||
first_steps:
|
||||
- 'Open mealie.DOMAIN in your browser'
|
||||
- 'Sign in: changeme@example.com / MyPassword'
|
||||
- 'Change the e-mail address and password straight away'
|
||||
- 'Sign in: changeme@example.com and the first password shown on the settings page'
|
||||
- 'Change the e-mail address to your own'
|
||||
- 'Import your first recipe by pasting a web page address'
|
||||
- 'Try the meal planner'
|
||||
deploy_fields:
|
||||
@@ -109,6 +129,9 @@ i18n:
|
||||
- env_var: SUBDOMAIN
|
||||
label: 'Subdomain'
|
||||
description: 'The subdomain this app answers on'
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: 'Admin password (changeme@example.com)'
|
||||
description: 'For the first sign-in: changeme@example.com and this password. Change it in your profile afterwards.'
|
||||
|
||||
# update_ladder — the test record: one tested step per line, oldest first (JSON flow mappings,
|
||||
# `09-update-architecture.md` §6.4 part 4). WRITTEN BY scripts/upgrade-test.py, never by hand;
|
||||
|
||||
@@ -41,6 +41,17 @@ deploy_fields:
|
||||
generate: "hex:16"
|
||||
locked_after_deploy: true
|
||||
|
||||
|
||||
# --- The setup gate (controller >= 0.280.0, `09` §3 decision 46) ---
|
||||
# The first visitor would create the admin. So a fresh install is closed to everyone but the household (a browser
|
||||
# signed in to the dashboard) until the first setup is done; n8n's own settings say so (measured on 9202 2026-09-29:
|
||||
# showSetupOnFirstLoad true -> false once the owner exists).
|
||||
setup_gate: true
|
||||
setup_done_probe:
|
||||
url: http://n8n:5678/rest/settings
|
||||
field: data.userManagement.showSetupOnFirstLoad
|
||||
done: "false"
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Vizuális workflow automatizálás - Zapier/IFTTT alternatíva"
|
||||
|
||||
@@ -80,7 +80,6 @@ deploy_fields:
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Retró játékgyűjtemény kezelő, böngésző és lejátszó"
|
||||
default_creds: "admin / admin"
|
||||
docs_url: "https://github.com/rommapp/romm/wiki"
|
||||
|
||||
use_cases:
|
||||
@@ -92,7 +91,7 @@ app_info:
|
||||
|
||||
first_steps:
|
||||
- "Nyisd meg az arcade.DOMAIN címet a böngészőben"
|
||||
- "Jelentkezz be az alapértelmezett admin / admin fiókkal"
|
||||
- "Az első megnyitáskor hozd létre az admin fiókodat"
|
||||
- "Változtasd meg azonnal a jelszót a Settings menüben"
|
||||
- "Töltsd fel a ROM fájlokat a Fájlkezelőben (FileBrowser) a roms/ mappába, platform mappákba rendezve (pl. roms/gba/, roms/snes/)"
|
||||
- "Indíts egy Scan-t a bal oldali menüben a ROM-ok beolvasásához"
|
||||
@@ -184,7 +183,6 @@ i18n:
|
||||
|
||||
app_info:
|
||||
tagline: "Retro game collection manager, browser and player"
|
||||
default_creds: "admin / admin"
|
||||
|
||||
use_cases:
|
||||
- "Sort and browse a retro game collection in your browser"
|
||||
@@ -195,7 +193,7 @@ i18n:
|
||||
|
||||
first_steps:
|
||||
- "Open arcade.DOMAIN in your browser"
|
||||
- "Sign in with the default admin / admin account"
|
||||
- "On the first visit, create your admin account"
|
||||
- "Change the password straight away, in the Settings menu"
|
||||
- "Upload the ROM files into the roms/ folder in the File manager (FileBrowser), sorted into platform folders (for example roms/gba/, roms/snes/)"
|
||||
- "Start a Scan from the menu on the left to read the ROMs in"
|
||||
|
||||
@@ -35,6 +35,13 @@ deploy_fields:
|
||||
locked_after_deploy: true
|
||||
description: "Az alkalmazás aldomainje"
|
||||
|
||||
|
||||
# --- The setup gate (controller >= 0.280.0, `09` §3 decision 46) ---
|
||||
# The first visitor would create the admin. So a fresh install is closed to everyone but the household (a browser
|
||||
# signed in to the dashboard) until the first setup is done. uptime-kuma says it only over socket.io, so the household presses "Done, I set it up"
|
||||
# on the app page.
|
||||
setup_gate: true
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Szolgáltatás monitoring - értesítés ha valami nem működik"
|
||||
|
||||
@@ -41,6 +41,15 @@ deploy_fields:
|
||||
generate: "hex:32"
|
||||
locked_after_deploy: true
|
||||
|
||||
# `09` §3 decision 45: wger starts with admin / adminadmin. The box replaces that password with this generated
|
||||
# one right after the install (after_install below); the app page shows it as the first password.
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: "Admin jelszó (admin)"
|
||||
type: password
|
||||
generate: "password:24"
|
||||
description: "Az első bejelentkezéshez: admin és ez a jelszó. Utána a beállításokban módosítható."
|
||||
locked_after_deploy: true
|
||||
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Edzésnapló - edzéstervek, haladás követés és testsúly napló"
|
||||
@@ -56,12 +65,23 @@ app_info:
|
||||
|
||||
first_steps:
|
||||
- 'Nyisd meg a fitness.DOMAIN címet a böngészőben'
|
||||
- 'Jelentkezz be: admin / adminadmin'
|
||||
- 'Változtasd meg azonnal a jelszót'
|
||||
- 'Jelentkezz be: admin és a Beállítások oldalon látható első jelszó'
|
||||
- 'Add meg az email címedet a beállításokban'
|
||||
- 'Hozd létre az edzéstervedet'
|
||||
- 'Kezdd el naplózni az edzéseidet'
|
||||
|
||||
|
||||
# --- After a fresh install (controller >= 0.279.0, decision 45) ---
|
||||
# Django's own set_password on the seeded admin. Measured on 9202 2026-09-29: afterwards adminadmin no longer signs in
|
||||
# at /en/user/login, the new one does.
|
||||
after_install:
|
||||
service: wger
|
||||
env: [ADMIN_PASSWORD]
|
||||
# The password is the LAST ARGUMENT (sys.argv[1]), never pasted into the code: a quote in it cannot break or change
|
||||
# the program (security review 2026-09-29). Django is set up the way manage.py does it (settings.main).
|
||||
command: ["python3", "-c", "import os, sys; sys.path.insert(0, '/home/wger/src'); os.chdir('/home/wger/src'); os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.main'); import django; django.setup(); from django.contrib.auth.models import User; u = User.objects.get(username='admin'); u.set_password(sys.argv[1]); u.save(); print('FELHOM_AFTER_INSTALL_OK')", "${ADMIN_PASSWORD}"]
|
||||
success: "FELHOM_AFTER_INSTALL_OK"
|
||||
|
||||
# --- Controller-side health probe ---
|
||||
healthcheck:
|
||||
checks:
|
||||
@@ -87,8 +107,8 @@ i18n:
|
||||
- 'An API, for fitness app integrations'
|
||||
first_steps:
|
||||
- 'Open fitness.DOMAIN in your browser'
|
||||
- 'Sign in: admin / adminadmin'
|
||||
- 'Change the password straight away'
|
||||
- 'Sign in: admin and the first password shown on the settings page'
|
||||
- 'Add your e-mail address in the settings'
|
||||
- 'Build your training plan'
|
||||
- 'Start logging your workouts'
|
||||
deploy_fields:
|
||||
@@ -100,3 +120,6 @@ i18n:
|
||||
description: 'The subdomain this app answers on'
|
||||
- env_var: SECRET_KEY
|
||||
label: 'Encryption key'
|
||||
- env_var: ADMIN_PASSWORD
|
||||
label: 'Admin password (admin)'
|
||||
description: 'For the first sign-in: admin and this password. Change it in the settings afterwards.'
|
||||
|
||||
@@ -22,6 +22,10 @@ services:
|
||||
# A DATABASE a wger_data kötetre mutat (/home/wger/db), oda, ahol a wger
|
||||
# saját alapértelmezett sqlite fájlja is volt -- így meglévő telepítés
|
||||
# adatai nem "tűnnek el" egy másik útvonalra.
|
||||
# R-712 (measured 2026-09-29 on 9202): behind traefik wger saw the request as http and refused a browser's
|
||||
# https Origin with "CSRF verification failed" — nobody could sign in from a browser.
|
||||
- CSRF_TRUSTED_ORIGINS=https://${SUBDOMAIN}.${DOMAIN}
|
||||
- X_FORWARDED_PROTO_HEADER_SET=True
|
||||
- DJANGO_DB_ENGINE=django.db.backends.sqlite3
|
||||
- DJANGO_DB_DATABASE=/home/wger/db/database.sqlite
|
||||
- DJANGO_DB_USER=wger
|
||||
|
||||
@@ -50,7 +50,6 @@ deploy_fields:
|
||||
# --- App info (info page content) ---
|
||||
app_info:
|
||||
tagline: "Screenshot és fájlmegosztó szerver ShareX/Flameshot integrációval"
|
||||
default_creds: "admin / zipline"
|
||||
docs_url: "https://zipline.diced.sh/docs/"
|
||||
|
||||
use_cases:
|
||||
@@ -62,8 +61,7 @@ app_info:
|
||||
|
||||
first_steps:
|
||||
- 'Nyisd meg az img.DOMAIN címet a böngészőben'
|
||||
- 'Jelentkezz be: admin / zipline'
|
||||
- 'Változtasd meg azonnal a jelszót'
|
||||
- 'Az első megnyitáskor hozd létre az admin fiókodat'
|
||||
- 'Konfiguráld a ShareX-et vagy Flameshot-ot az API URL-lel'
|
||||
- 'Tölts fel egy screenshot-ot a teszteléshez'
|
||||
|
||||
@@ -90,7 +88,6 @@ i18n:
|
||||
description: 'A ShareX/Flameshot server - screenshots and file sharing'
|
||||
app_info:
|
||||
tagline: 'A screenshot and file sharing server that works with ShareX/Flameshot'
|
||||
default_creds: 'admin / zipline'
|
||||
use_cases:
|
||||
- 'Screenshots upload themselves from ShareX/Flameshot'
|
||||
- 'Shorten a URL and share text (paste)'
|
||||
@@ -99,8 +96,7 @@ i18n:
|
||||
- 'User accounts and invitations'
|
||||
first_steps:
|
||||
- 'Open img.DOMAIN in your browser'
|
||||
- 'Sign in: admin / zipline'
|
||||
- 'Change the password straight away'
|
||||
- 'On the first visit, create your admin account'
|
||||
- 'Point ShareX or Flameshot at the API address'
|
||||
- 'Upload a screenshot to check it works'
|
||||
prerequisites:
|
||||
|
||||
Reference in New Issue
Block a user