diff --git a/CHANGELOG.md b/CHANGELOG.md index 471393b..9253379 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## Every step keeps its own `.felhom.yml` (2026-09-24 night, R-664) + +**No `image:` line moved.** Controller v0.269.0 reads them. + +- `steps/.felhom.yml` beside every step's compose: the box judges a step with ITS probe, memory + request and applied record, not the head's. `ladder.step_meta_file`, `ladder.strip_ladder_block` (a step's copy + carries no ladder). +- **Gate rule 4b:** a step without its `.felhom.yml`, or one without a healthcheck while the template has one, is + refused. Decoys: the file missing; a file with the right NAME and no healthcheck (red-proof: rule off → both pass + wrongly). Suite 86 cases OK. +- **Writer:** `--write-ladder` also keeps the superseded step's `.felhom.yml`. **Backfill** (`steps_meta_backfill.py`, + one-off): 8 files, each from the newest commit whose compose names that step's images. + ## Every step keeps its own definition — the box can climb one step at a time (2026-09-24, `09` §6.4 part 5, R-653, R-656, R-663) **No `image:` line moved.** The box half ships in controller v0.268.0. diff --git a/scripts/check-test-record.py b/scripts/check-test-record.py index e1d8103..76a6835 100644 --- a/scripts/check-test-record.py +++ b/scripts/check-test-record.py @@ -22,6 +22,8 @@ WHAT IT CHECKS, per template that carries `update_ladder:` (format and field rul 4. every entry but the newest carries its OWN definition at `steps/.yml`, whose images per service are EXACTLY that entry's `to` (`09` §6.4 part 5: the box pins that file, one step per press). The name alone is not the fact: the file's own `image:` lines are read. + 4b. ... and its own `.felhom.yml` at `steps/.felhom.yml` (R-664), with a healthcheck + when the template has one. A template WITHOUT a ladder passes here — it has never been moved since the gate existed, and its first move is refused by the twin unless that move brings the first entry. @@ -65,6 +67,13 @@ def check_app(app_dir): got = ladder.images_in(open(sp, encoding="utf-8").read()) if got != to: problems.append("%s names %s, but entry %d's `to` is %s" % (ladder.step_file(to), got, i + 1, to)) + # rule 4b (R-664, 2026-09-24): the step's own .felhom.yml — the box judges the step with it. + smp = os.path.join(app_dir, ladder.step_meta_file(to)) + if not os.path.isfile(smp): + problems.append("entry %d of %d has no %s — the box would judge the step with the head's probe (R-664)" + % (i + 1, len(entries), ladder.step_meta_file(to))) + elif "healthcheck:" not in open(smp, encoding="utf-8").read() and "healthcheck:" in open(os.path.join(app_dir, ".felhom.yml"), encoding="utf-8").read(): + problems.append("%s carries no healthcheck: while the template does — not a real step file" % ladder.step_meta_file(to)) if entries: current = ladder.images_in(open(comp, encoding="utf-8").read()) head = entries[-1].get("to") diff --git a/scripts/ladder.py b/scripts/ladder.py index 75a26c6..8970cfb 100644 --- a/scripts/ladder.py +++ b/scripts/ladder.py @@ -210,3 +210,19 @@ def step_key(to): def step_file(to): """The step definition's path RELATIVE to the template directory.""" return "steps/%s.yml" % step_key(to) + + +def step_meta_file(to): + """The step's own `.felhom.yml` (R-664, 2026-09-24): its probe, memory limits and applied record — the + box judges the step with it. RELATIVE to the template directory.""" + return "steps/%s.felhom.yml" % step_key(to) + + +def strip_ladder_block(felhom_text): + """A `.felhom.yml` without its update_ladder block (and the header comment the writer puts above it): + a step's own copy carries no ladder — only the template's is read for one.""" + lines = felhom_text.splitlines() + for i, l in enumerate(lines): + if l.startswith("# update_ladder") or l.startswith("update_ladder:"): + return "\n".join(lines[:i]).rstrip("\n") + "\n" + return felhom_text diff --git a/scripts/steps_meta_backfill.py b/scripts/steps_meta_backfill.py new file mode 100644 index 0000000..2e560c9 --- /dev/null +++ b/scripts/steps_meta_backfill.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +"""steps_meta_backfill.py — ONE-OFF (2026-09-24 night, R-664): write `steps/.felhom.yml` beside every step +file, from the NEWEST commit whose compose names that step's images — the .felhom.yml served WITH that +definition — without its update_ladder block. Never overwrites.""" +import os, subprocess, sys +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import ladder # noqa: E402 +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +def git(*a): + return subprocess.run(["git", "-C", ROOT] + list(a), capture_output=True, text=True, check=True).stdout + + +def main(): + n = 0 + for app in sorted(os.listdir(os.path.join(ROOT, "templates"))): + d = os.path.join(ROOT, "templates", app) + fy = os.path.join(d, ".felhom.yml") + if not os.path.isfile(fy): + continue + entries, _, errs = ladder.parse(open(fy, encoding="utf-8").read()) + if errs or len(entries) < 2: + continue + commits = git("log", "--format=%H", "--", "templates/%s" % app).split() + for i, e in enumerate(entries[:-1]): + dst = os.path.join(d, ladder.step_meta_file(e["to"])) + if os.path.exists(dst): + continue + for c in commits: + try: + comp = git("show", "%s:templates/%s/docker-compose.yml" % (c, app)) + except subprocess.CalledProcessError: + continue + if ladder.images_in(comp) == e["to"]: + meta = git("show", "%s:templates/%s/.felhom.yml" % (c, app)) + open(dst, "w", encoding="utf-8").write(ladder.strip_ladder_block(meta)) + print("WROTE %-10s entry %d -> %s from %s" % (app, i + 1, ladder.step_meta_file(e["to"]), c[:12])) + n += 1 + break + else: + print("MISS %-10s entry %d" % (app, i + 1)) + print("steps_meta_backfill: %d written" % n) + + +if __name__ == "__main__": + main() diff --git a/scripts/test_gate_decoys.py b/scripts/test_gate_decoys.py index 0dcef82..9c9c09f 100644 --- a/scripts/test_gate_decoys.py +++ b/scripts/test_gate_decoys.py @@ -437,16 +437,23 @@ def test_record_cases(clone): two = ladder_of(tr_entry({"navidrome": prev}, mid, {"navidrome": TR_D1}), tr_entry(mid, frm, {"navidrome": TR_D1})) step_rel = "templates/navidrome/" + _l.step_file(mid) + meta_rel = "templates/navidrome/" + _l.step_meta_file(mid) + meta_body = lambda t: _l.strip_ladder_block(io.open(os.path.join(clone, NF), encoding="utf-8").read()) step_body = lambda t: swap_image("navidrome", old, mid["navidrome"])(io.open(os.path.join(clone, NC), encoding="utf-8").read()) case_tr_static("FACT: a two-step ladder with NO steps/ file for the first step", clone, [(NF, two)], 1, ("has no definition",)) case_tr_static("GENUINE: a two-step ladder whose first step carries its definition", clone, - [(NF, two), (step_rel, step_body)], 0) + [(NF, two), (step_rel, step_body), (meta_rel, meta_body)], 0) case_tr_static("DECOY: the steps/ file has the right NAME and names the head's image", clone, - [(NF, two), (step_rel, lambda t: io.open(os.path.join(clone, NC), encoding="utf-8").read())], + [(NF, two), (step_rel, lambda t: io.open(os.path.join(clone, NC), encoding="utf-8").read()), (meta_rel, meta_body)], 1, ("names",)) case_tr_static("DECOY: the step's definition sits beside the template under another name", clone, [(NF, two), ("templates/navidrome/steps/0.2.0.yml", step_body)], 1, ("has no definition",)) + # R-664: the step's own .felhom.yml + case_tr_static("FACT: the step has its compose but no .felhom.yml", clone, + [(NF, two), (step_rel, step_body)], 1, ("R-664",)) + case_tr_static("DECOY: the step's .felhom.yml exists by NAME and holds no healthcheck", clone, + [(NF, two), (step_rel, step_body), (meta_rel, lambda t: "display_name: Navidrome\n")], 1, ("not a real step file",)) def main(): gate = os.path.join(ROOT, "scripts", "check-engine-major.py") diff --git a/scripts/test_ladder_writer.py b/scripts/test_ladder_writer.py index 2fe9460..ac9f037 100644 --- a/scripts/test_ladder_writer.py +++ b/scripts/test_ladder_writer.py @@ -122,6 +122,9 @@ class WriterTest(unittest.TestCase): sp = os.path.join(self.tmp, "templates", "navidrome", ladder.step_file({"navidrome": "deluan/navidrome:" + NEXT})) self.assertTrue(os.path.isfile(sp), out) self.assertEqual(open(sp).read(), at_step1, "the step file must be the definition AS SERVED, fixes included") + smp = os.path.join(self.tmp, "templates", "navidrome", ladder.step_meta_file({"navidrome": "deluan/navidrome:" + NEXT})) + self.assertTrue(os.path.isfile(smp), "the step's own .felhom.yml (R-664) was not written") + self.assertNotIn("update_ladder:", open(smp).read()) import subprocess r = subprocess.run([sys.executable, os.path.join(HERE, "check-test-record.py"), "--root", self.tmp, "navidrome"], capture_output=True, text=True) diff --git a/scripts/upgrade-test.py b/scripts/upgrade-test.py index 3f7f720..e77021a 100755 --- a/scripts/upgrade-test.py +++ b/scripts/upgrade-test.py @@ -832,6 +832,10 @@ def write_ladder(argv) -> int: sp.parent.mkdir(parents=True, exist_ok=True) sp.write_text(comp) print(f"STEP {app}: the superseded step {cur} keeps its definition at {ladder.step_file(cur)}") + smp = tdir / ladder.step_meta_file(cur) + if not smp.exists(): # R-664: and its own .felhom.yml, without the ladder + smp.write_text(ladder.strip_ladder_block(fy_p.read_text())) + print(f"STEP {app}: … and its .felhom.yml at {ladder.step_meta_file(cur)}") # move the compose, per service, on that service's own image: line out, svc = [], None for line in comp.splitlines(): diff --git a/templates/emby/steps/59645352efe5f728.felhom.yml b/templates/emby/steps/59645352efe5f728.felhom.yml new file mode 100644 index 0000000..324ee0b --- /dev/null +++ b/templates/emby/steps/59645352efe5f728.felhom.yml @@ -0,0 +1,119 @@ +# ============================================================================= +# .felhom.yml - App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "Emby" +description: "Személyes média szerver élő TV és DVR támogatással" +category: "media" +subdomain: "emby" +slug: "emby" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "512M" + mem_limit: "2048M" + pi_compatible: false + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + userdata: + - path: media + class: excluded # pure reader of the shared tree (:ro); state lives in volumes + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "emby" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: HDD_PATH + label: "Médiatár útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja" + locked_after_deploy: true + +# --- App info (info page content) --- +app_info: + tagline: "Személyes média szerver élő TV és DVR támogatással" + docs_url: "https://emby.media/support/articles/Home.html" + + use_cases: + - 'Filmek, sorozatok, zene és fotók kezelése egy helyen' + - 'Élő TV nézés és felvétel (DVR) TV tunerrel' + - 'Automatikus transzkódolás bármilyen eszközhöz' + - 'Szülői felügyelet és felhasználói profilok' + - 'Szinkronizálás offline megtekintéshez mobilon' + + first_steps: + - 'Nyisd meg az emby.DOMAIN címet a böngészőben' + - 'Kövesd a beállítás varázslót' + - 'Hozd létre az admin fiókot' + - 'Add hozzá a médiatárat a /media mappából' + - 'Telepítsd az Emby alkalmazást eszközeidre' + + prerequisites: + - 'Külső HDD szükséges a médiafájlok tárolásához' + - 'Legalább 2 GB szabad RAM ajánlott' + - 'Emby Premiere előfizetés a prémium funkciókhoz (opcionális)' + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: api + port: 8096 + path: "/emby/system/ping" + expect: + status: 200 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'A personal media server with live TV and recording' + app_info: + tagline: 'A personal media server with live TV and recording' + use_cases: + - 'Films, series, music and photos in one place' + - 'Watch and record live TV, with a TV tuner' + - 'It re-encodes on the fly for whatever device you are on' + - 'Parental controls and a profile for each person' + - 'Sync to a phone to watch offline' + first_steps: + - 'Open emby.DOMAIN in your browser' + - 'Follow the setup wizard' + - 'Create the admin account' + - 'Add your library from the /media folder' + - 'Install the Emby app on your devices' + prerequisites: + - 'An external hard drive is needed to keep the media files on' + - 'At least 2 GB of free RAM is recommended' + - 'An Emby Premiere subscription for the premium features (optional)' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' + - env_var: HDD_PATH + label: 'Media library path' + description: 'The path to the external hard drive' + placeholder: '/mnt/felhom-drives/hdd_1' diff --git a/templates/ghost/steps/2ca9e0b50e635ffa.felhom.yml b/templates/ghost/steps/2ca9e0b50e635ffa.felhom.yml new file mode 100644 index 0000000..0d86de4 --- /dev/null +++ b/templates/ghost/steps/2ca9e0b50e635ffa.felhom.yml @@ -0,0 +1,94 @@ +# ============================================================================= +# .felhom.yml - App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "Ghost" +description: "Professzionális blog és hírlevél platform" +category: "productivity" +subdomain: "blog" +slug: "ghost" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" +# Bare "/" is the public blog; the admin panel / setup wizard lives at /ghost/. +open_path: "/ghost/" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "150M" + mem_limit: "512M" + pi_compatible: false + needs_hdd: false + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "blog" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + +# --- App info (info page content) --- +app_info: + tagline: "Professzionális blog és hírlevél platform" + docs_url: "https://ghost.org/docs/" + + use_cases: + - 'Professzionális blog indítása és üzemeltetése' + - 'Hírlevél küldés beépített email funkcióval' + - 'SEO-optimalizált tartalom publikálás' + - 'Tagság és fizetős tartalom kezelés' + - 'Markdown és vizuális szerkesztő' + + first_steps: + - 'Nyisd meg a blog.DOMAIN/ghost/ címet a böngészőben' + - 'Hozd létre az admin fiókot a beállítás varázslóban' + - 'Írd meg és publikáld az első posztodat' + - 'Személyre szabd a témát és beállításokat' + + prerequisites: + - 'x86 processzor szükséges' + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: http + port: 2368 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'A professional blog and newsletter platform' + app_info: + tagline: 'A professional blog and newsletter platform' + use_cases: + - 'Start and run a professional blog' + - 'Send a newsletter with the built-in e-mail feature' + - 'Publish content that search engines can read' + - 'Memberships and paid content' + - 'A Markdown editor and a visual one' + first_steps: + - 'Open blog.DOMAIN/ghost/ in your browser' + - 'Create the admin account in the setup wizard' + - 'Write and publish your first post' + - 'Make the theme and the settings your own' + prerequisites: + - 'An x86 processor is needed' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' diff --git a/templates/immich/steps/0b8272068aab36bf.felhom.yml b/templates/immich/steps/0b8272068aab36bf.felhom.yml new file mode 100644 index 0000000..c42dfc0 --- /dev/null +++ b/templates/immich/steps/0b8272068aab36bf.felhom.yml @@ -0,0 +1,144 @@ +# ============================================================================= +# .felhom.yml — App metadata for felhom-controller +# ============================================================================= +# Place alongside docker-compose.yml in each stack directory: +# /opt/docker/stacks/immich/.felhom.yml +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "Immich" +description: "Fotók és videók kezelése (Google Photos alternatíva)" +category: "media" +subdomain: "photos" + +# --- Asset slug --- +slug: "immich" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "2048M" + mem_limit: "4096M" + pi_compatible: false + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + hdd: + - path: appdata/immich + class: mandatory # managed upload library — DB-referenced (SQ3: restore-without = broken) + userdata: + - path: media/photos + class: optional # external library, :ro — precious but re-scanned (explicit overrides ro-default) + +# --- Deploy fields --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "photos" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: DB_PASSWORD + label: "Adatbázis jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: HDD_PATH + label: "Adattárolási útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja, ahol a fotók és videók tárolódnak" + locked_after_deploy: true + +# --- App info (info page content) --- +app_info: + tagline: 'Google Photos alternatíva - automatikus fotó mentés és rendszerezés' + docs_url: 'https://immich.app/docs/overview/introduction' + + use_cases: + - 'Fotók és videók automatikus mentése telefonról' + - 'Arc- és tárgyfelismerés gépi tanulással' + - 'Térképes megjelenítés helyszín alapján' + - 'Emlékek és visszatekintések automatikus generálása' + - 'Albumok létrehozása és megosztása családtagokkal' + + first_steps: + - 'Nyisd meg a photos.DOMAIN címet a böngészőben' + - 'Hozd létre az admin fiókot' + - 'Telepítsd az Immich alkalmazást a telefonodra (Android/iOS)' + - 'Állítsd be az automatikus feltöltést az alkalmazásban' + - 'Hívd meg a családtagokat külön fiókokkal' + # MOUNT-READY, REGISTRATION PENDING: a megosztott média/photos mappa be van csatolva + # /external/photos néven (csak olvasható), de az Immich CSAK akkor látja, ha az + # adminfelületen (Administration → External Libraries) regisztrálod a /external/photos + # útvonalat. Compose ezt NEM teszi meg automatikusan — ez egy telepítés utáni lépés. + - 'Külső könyvtár (opcionális): Administration → External Libraries → add /external/photos' + + prerequisites: + - 'Külső HDD szükséges a fotók és videók tárolásához' + - 'Legalább 4 GB szabad RAM ajánlott (gépi tanulás funkciókhoz)' + - 'x86 processzor szükséges (nem fut Raspberry Pi-n)' + +# --- Controller-side health probe --- +healthcheck: + # container: no exact match and FOUR `immich-*` containers, so the old prefix rule picked whichever the + # container list happened to yield first — it could have been `immich-postgres` (R-630) + container: immich-server + checks: + - type: api + port: 2283 + path: "/api/server/ping" + expect: + status: 200 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'Photos and videos in one place (a Google Photos alternative)' + app_info: + tagline: 'A Google Photos alternative - your photos back themselves up and sort themselves' + use_cases: + - 'Photos and videos back themselves up from your phone' + - 'It recognises faces and objects on its own' + - 'See where a photo was taken, on a map' + - 'Memories and look-backs, put together for you' + - 'Build albums and share them with the household' + first_steps: + - 'Open photos.DOMAIN in your browser' + - 'Create the admin account' + - 'Install the Immich app on your phone (Android/iOS)' + - 'Turn on automatic upload in the app' + - 'Invite the household, each with their own account' + - 'An external library (optional): Administration -> External Libraries -> add /external/photos' + prerequisites: + - 'An external hard drive is needed to keep the photos and videos on' + - 'At least 4 GB of free RAM is recommended (for the machine learning features)' + - 'An x86 processor is needed (it does not run on a Raspberry Pi)' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' + - env_var: DB_PASSWORD + label: 'Database password' + - env_var: HDD_PATH + label: 'Data storage path' + description: 'The path to the external hard drive where the photos and videos are kept' + placeholder: '/mnt/felhom-drives/hdd_1' diff --git a/templates/n8n/steps/9e432b2ae70c14e3.felhom.yml b/templates/n8n/steps/9e432b2ae70c14e3.felhom.yml new file mode 100644 index 0000000..b152a90 --- /dev/null +++ b/templates/n8n/steps/9e432b2ae70c14e3.felhom.yml @@ -0,0 +1,103 @@ +# ============================================================================= +# .felhom.yml - App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "n8n" +description: "Workflow automatizálás vizuális szerkesztővel" +category: "productivity" +subdomain: "auto" +slug: "n8n" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "512M" + mem_limit: "1536M" + pi_compatible: false + needs_hdd: false + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "auto" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: N8N_ENCRYPTION_KEY + label: "Titkosítási kulcs" + type: secret + generate: "hex:16" + locked_after_deploy: true + +# --- App info (info page content) --- +app_info: + tagline: "Vizuális workflow automatizálás - Zapier/IFTTT alternatíva" + docs_url: "https://docs.n8n.io/" + + use_cases: + - 'Alkalmazások összekapcsolása vizuális workflow szerkesztővel' + - 'Automatizálás: email, Telegram, webhook, fájl feldolgozás' + - '400+ integráció (Google, Slack, Notion, GitHub, stb.)' + - 'Időzített feladatok (cron) és webhook triggerek' + - 'AI munkafolyamatok LLM integrációval' + + first_steps: + - 'Nyisd meg az auto.DOMAIN címet a böngészőben' + - 'Hozd létre az admin fiókot' + - 'Próbálj ki egy sablon workflow-t a Template galériából' + - 'Hozd létre az első saját munkafolyamatot' + + prerequisites: + - 'x86 processzor szükséges' + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: api + port: 5678 + path: "/healthz" + expect: + status: 200 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'Workflow automation with a visual editor' + app_info: + tagline: 'Visual workflow automation - a Zapier/IFTTT alternative' + use_cases: + - 'Wire apps together in a visual workflow editor' + - 'Automate e-mail, Telegram, webhooks and file handling' + - '400+ integrations (Google, Slack, Notion, GitHub and more)' + - 'Scheduled jobs (cron) and webhook triggers' + - 'AI workflows with an LLM in them' + first_steps: + - 'Open auto.DOMAIN in your browser' + - 'Create the admin account' + - 'Try a ready-made workflow from the Template gallery' + - 'Build your first workflow of your own' + prerequisites: + - 'An x86 processor is needed' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' + - env_var: N8N_ENCRYPTION_KEY + label: 'Encryption key' diff --git a/templates/navidrome/steps/755d09b083f757a0.felhom.yml b/templates/navidrome/steps/755d09b083f757a0.felhom.yml new file mode 100644 index 0000000..70d6c05 --- /dev/null +++ b/templates/navidrome/steps/755d09b083f757a0.felhom.yml @@ -0,0 +1,117 @@ +# ============================================================================= +# .felhom.yml - App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "Navidrome" +description: "Könnyű zene szerver Subsonic API támogatással" +category: "media" +subdomain: "music" +slug: "navidrome" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "50M" + mem_limit: "256M" + pi_compatible: true + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + userdata: + - path: media/music + class: excluded # re-rippable bulk, :ro, shared tree + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "music" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: HDD_PATH + label: "Zenegyűjtemény útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja, ahol a zenefájlok tárolódnak" + locked_after_deploy: true + +# --- App info (info page content) --- +app_info: + tagline: "Könnyű zene szerver - streameld a saját zenegyűjteményedet" + docs_url: "https://www.navidrome.org/docs/" + + use_cases: + - 'Saját zenegyűjtemény streamelése bármilyen eszközről' + - 'Subsonic API kompatibilis mobil alkalmazások használata' + - 'Lejátszási listák, kedvencek és értékelések kezelése' + - 'Automatikus metaadat és borítókép letöltés' + - 'Több felhasználó külön könyvtárral és beállításokkal' + + first_steps: + - 'Nyisd meg a music.DOMAIN címet a böngészőben' + - 'Az első felhasználó automatikusan admin lesz' + - 'Hozd létre a fiókodat és várd meg az első szkennelést' + - 'Telepíts Subsonic-kompatibilis alkalmazást (pl. Subtracks, play:Sub)' + - 'Add meg a szerver címet: https://music.DOMAIN' + + prerequisites: + - 'Külső HDD szükséges a zenefájlok tárolásához' + - 'Zenefájlok mappákba rendezve (pl. Előadó/Album/szám.flac)' + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: api + port: 4533 + path: "/ping" + expect: + status: 200 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'A light music server with Subsonic API support' + app_info: + tagline: 'A light music server - stream your own music collection' + use_cases: + - 'Stream your own music collection to any device' + - 'Use any Subsonic-compatible phone app' + - 'Playlists, favourites and ratings' + - 'Details and cover art arrive on their own' + - 'Several people, each with their own library and settings' + first_steps: + - 'Open music.DOMAIN in your browser' + - 'The first user becomes the admin automatically' + - 'Create your account and wait for the first scan' + - 'Install a Subsonic-compatible app (Subtracks or play:Sub, for example)' + - 'Give it the server address: https://music.DOMAIN' + prerequisites: + - 'An external hard drive is needed to keep the music files on' + - 'Music files sorted into folders (Artist/Album/track.flac, for example)' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' + - env_var: HDD_PATH + label: 'Music collection path' + description: 'The path to the external hard drive where the music files are kept' + placeholder: '/mnt/felhom-drives/hdd_1' diff --git a/templates/nextcloud/steps/eef2e4afe1218021.felhom.yml b/templates/nextcloud/steps/eef2e4afe1218021.felhom.yml new file mode 100644 index 0000000..f6ce82d --- /dev/null +++ b/templates/nextcloud/steps/eef2e4afe1218021.felhom.yml @@ -0,0 +1,171 @@ +# ============================================================================= +# .felhom.yml - App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "Nextcloud" +description: "Saját felhő tárhely - Google Drive/Dropbox alternatíva" +category: "files" +subdomain: "cloud" +slug: "nextcloud" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "256M" + mem_limit: "1024M" + pi_compatible: false + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + hdd: + - path: appdata/nextcloud + class: mandatory # THE user files — oc_filecache/shares reference them + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "cloud" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: DB_PASSWORD + label: "Adatbázis jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: MYSQL_ROOT_PASSWORD + label: "MariaDB root jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: NEXTCLOUD_ADMIN_USER + label: "Admin felhasználónév" + type: text + default: "admin" + locked_after_deploy: true + + - env_var: NEXTCLOUD_ADMIN_PASSWORD + label: "Admin jelszó" + type: password + generate: "password:16" + description: "Első bejelentkezéshez. Utána a webes felületen módosítható." + locked_after_deploy: false + + - env_var: HDD_PATH + label: "Adattárolási útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja" + locked_after_deploy: true + +# --- App info (info page content) --- +app_info: + tagline: "A saját Google Drive-od - fájlok, naptár, névjegyek egy helyen" + default_creds: "Az admin fiók adatait a telepítéskor adod meg" + docs_url: "https://docs.nextcloud.com/server/latest/user_manual/" + + use_cases: + - 'Fájlok szinkronizálása és megosztása eszközök között' + - 'Naptár és névjegyek szinkronizálás (CalDAV/CardDAV)' + - 'Dokumentumok közös szerkesztése (OnlyOffice integrációval)' + - 'Fotó és videó automatikus feltöltés telefonról' + - 'Alkalmazásbolt - kibővíthető funkciók (Notes, Tasks, Forms, stb.)' + + first_steps: + - 'Nyisd meg a cloud.DOMAIN címet a böngészőben' + - 'Jelentkezz be a telepítéskor megadott admin fiókkal' + - 'Telepítsd a Nextcloud asztali alkalmazást a számítógépedre' + - 'Telepítsd a Nextcloud mobil alkalmazást a telefonodra' + - 'Hívd meg a családtagokat felhasználói fiókok létrehozásával' + + prerequisites: + - 'Külső HDD szükséges a fájlok tárolásához' + - 'Legalább 1 GB szabad RAM (Nextcloud + MariaDB + Redis)' + - 'x86 processzor ajánlott a legjobb teljesítményhez' + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: api + port: 80 + path: "/status.php" + expect: + status: 200 + body_contains: "installed" + +# --- App-email mapping (apps → in-controller shim → hub → Resend) --- +# Nextcloud (Symfony Mailer) has no env to skip TLS cert verification and opportunistically STARTTLS-upgrades, +# so it can't use the self-signed :2525 listener → tls_mode=plaintext points it at :2526 (STARTTLS NOT +# advertised → no upgrade attempted; plaintext on the single-tenant app bridge — accepted posture). +# Nextcloud SPLITS the From into local-part + domain, so from_var=MAIL_FROM_ADDRESS (local) + +# from_domain_var=MAIL_DOMAIN → nextcloud@felhom.eu. No security_var (SMTP_SECURE stays empty = no TLS); +# SMTP_NAME/PASSWORD unset (no auth). The official image reads these via getenv() on every boot. +smtp_mapping: + tls_mode: plaintext + host_var: SMTP_HOST + port_var: SMTP_PORT + from_var: MAIL_FROM_ADDRESS + from_domain_var: MAIL_DOMAIN + from_local: nextcloud + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: 'Your own cloud storage - a Google Drive/Dropbox alternative' + app_info: + tagline: 'Your own Google Drive - files, calendar and contacts in one place' + default_creds: 'You set the admin account details at install time' + use_cases: + - 'Sync and share files between your devices' + - 'Calendar and contact sync (CalDAV/CardDAV)' + - 'Work on a document together (with the OnlyOffice integration)' + - 'Photos and videos upload themselves from your phone' + - 'An app store - more features when you want them (Notes, Tasks, Forms and more)' + first_steps: + - 'Open cloud.DOMAIN in your browser' + - 'Sign in with the admin account you set at install time' + - 'Install the Nextcloud desktop app on your computer' + - 'Install the Nextcloud mobile app on your phone' + - 'Invite the household by creating an account for each of them' + prerequisites: + - 'An external hard drive is needed to keep the files on' + - 'At least 1 GB of free RAM (Nextcloud + MariaDB + Redis)' + - 'An x86 processor is recommended for the best speed' + deploy_fields: + - env_var: DOMAIN + label: 'Domain' + description: 'The server domain name' + - env_var: SUBDOMAIN + label: 'Subdomain' + description: 'The subdomain this app answers on' + - env_var: DB_PASSWORD + label: 'Database password' + - env_var: HDD_PATH + label: 'Data storage path' + description: 'The path to the external hard drive' + placeholder: '/mnt/felhom-drives/hdd_1' + - env_var: MYSQL_ROOT_PASSWORD + label: 'MariaDB root password' + - env_var: NEXTCLOUD_ADMIN_USER + label: 'Admin user name' + - env_var: NEXTCLOUD_ADMIN_PASSWORD + label: 'Admin password' + description: 'For the first sign-in. You can change it in the app afterwards.' diff --git a/templates/romm/steps/7f9c6a74b5891f8e.felhom.yml b/templates/romm/steps/7f9c6a74b5891f8e.felhom.yml new file mode 100644 index 0000000..cf4f22f --- /dev/null +++ b/templates/romm/steps/7f9c6a74b5891f8e.felhom.yml @@ -0,0 +1,236 @@ +# ============================================================================= +# .felhom.yml — App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "RomM" +description: "Retró játékgyűjtemény kezelő" +category: "media" +subdomain: "arcade" +slug: "romm" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-22" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "300M" + mem_limit: "1280M" + pi_compatible: false + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + userdata: + - path: roms + class: optional # ruled: curated ROM sets often not re-acquirable + hdd: + - path: appdata/romm/resources + class: excluded # scraper cache, re-derivable + +# --- Customer-facing folder annotation (R-75) --- +data_paths: + - path: roms + root: userdata + role: library + label: "ROM gyűjtemény" + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "arcade" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: DB_PASSWORD + label: "Adatbázis jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: MYSQL_ROOT_PASSWORD + label: "MariaDB root jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: ROMM_AUTH_SECRET_KEY + label: "Hitelesítési titkosítási kulcs" + type: secret + generate: "hex:32" + locked_after_deploy: true + + - env_var: HDD_PATH + label: "Adattárolási útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja, ahol a ROM-ok és borítóképek tárolódnak" + locked_after_deploy: true + +# --- 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: + - "Retró játékgyűjtemény rendszerezése és böngészése webes felületen" + - "Játékok metaadatainak automatikus letöltése — borítók, leírások, értékelések" + - "Platformonkénti szűrés és keresés a teljes gyűjteményben" + - "ROM fájlok webes feltöltése és letöltése" + - "Többfelhasználós hozzáférés a háztartás tagjai számára" + + first_steps: + - "Nyisd meg az arcade.DOMAIN címet a böngészőben" + - "Jelentkezz be az alapértelmezett admin / admin fiókkal" + - "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" + - "Opcionális: állíts be metaadat-szolgáltatókat a borítóképek és leírások automatikus letöltéséhez (lásd lent)" + + prerequisites: + - "Külső HDD szükséges a ROM fájlok és borítóképek tárolásához" + - "Legalább 1 GB szabad RAM ajánlott (MariaDB + Redis + RomM)" + - "ROM fájlok platform mappákba rendezve (pl. roms/gba/, roms/snes/)" + +# --- Optional config (configurable before or after deployment) --- +optional_config: + - group: "Metaadat-szolgáltatók" + description: "Játékok borítóinak, leírásainak és értékeléseinek automatikus letöltéséhez. Legalább az IGDB beállítása ajánlott. Mindegyik ingyenesen használható regisztráció után." + fields: + - env_var: IGDB_CLIENT_ID + label: "IGDB Client ID" + type: text + help_url: "https://api-docs.igdb.com/#getting-started" + help_text: "1) Regisztrálj / jelentkezz be a Twitch fejlesztői portálon (dev.twitch.tv). 2) Hozz létre egy új alkalmazást (bármilyen névvel). 3) Másold be a Client ID-t." + + - env_var: IGDB_CLIENT_SECRET + label: "IGDB Client Secret" + type: secret_input + help_text: "A Twitch alkalmazásod Client Secret-je (a „New Secret\" gombbal generálhatod)." + + - env_var: STEAMGRIDDB_API_KEY + label: "SteamGridDB API Key" + type: text + help_url: "https://www.steamgriddb.com/profile/preferences/api" + help_text: "Regisztrálj a SteamGridDB oldalon, majd a Preferences → API fül alatt kattints a „Generate API key\" gombra." + + - env_var: SCREENSCRAPER_USER + label: "ScreenScraper felhasználónév" + type: text + help_url: "https://www.screenscraper.fr/" + help_text: "Regisztrálj a screenscraper.fr oldalon. A felhasználóneved lesz az API felhasználónév." + + - env_var: SCREENSCRAPER_PASSWORD + label: "ScreenScraper jelszó" + type: secret_input + help_text: "A screenscraper.fr fiókod jelszava." + + - env_var: MOBYGAMES_API_KEY + label: "MobyGames API Key" + type: text + help_url: "https://www.mobygames.com/info/api/" + help_text: "Regisztrálj a MobyGames oldalon, majd az API oldalon igényelj kulcsot. Részletes játékinformációkat és krediteket biztosít." + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: http + port: 8080 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: "Retro game collection manager" + + data_paths: + - path: roms + label: "ROM collection" + + deploy_fields: + - env_var: DOMAIN + label: "Domain" + description: "The server domain name" + + - env_var: SUBDOMAIN + label: "Subdomain" + description: "The subdomain this app answers on" + + - env_var: DB_PASSWORD + label: "Database password" + + - env_var: MYSQL_ROOT_PASSWORD + label: "MariaDB root password" + + - env_var: ROMM_AUTH_SECRET_KEY + label: "Sign-in encryption key" + + - env_var: HDD_PATH + label: "Data storage path" + placeholder: "/mnt/felhom-drives/hdd_1" + description: "The path to the external hard drive where the ROMs and cover art are kept" + + 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" + - "Game details download themselves - cover art, descriptions, ratings" + - "Filter and search the whole collection by platform" + - "Upload and download ROM files in your browser" + - "Several people in the household can have their own account" + + first_steps: + - "Open arcade.DOMAIN in your browser" + - "Sign in with the default admin / 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" + - "Optional: set up metadata providers so cover art and descriptions download themselves (see below)" + + prerequisites: + - "An external hard drive is needed to keep the ROM files and cover art on" + - "At least 1 GB of free RAM is recommended (MariaDB + Redis + RomM)" + - "ROM files sorted into platform folders (for example roms/gba/, roms/snes/)" + + optional_config: + - match_group: "Metaadat-szolgáltatók" + group: "Metadata providers" + description: "So that cover art, descriptions and ratings download themselves. IGDB is the one worth setting up first. All of them are free after you sign up." + fields: + - env_var: IGDB_CLIENT_ID + label: "IGDB Client ID" + help_text: '1) Sign up or sign in on the Twitch developer portal (dev.twitch.tv). 2) Create a new application (any name will do). 3) Copy the Client ID across.' + + - env_var: IGDB_CLIENT_SECRET + label: "IGDB Client Secret" + help_text: 'The Client Secret of your Twitch application (the "New Secret" button makes one).' + + - env_var: STEAMGRIDDB_API_KEY + label: "SteamGridDB API Key" + help_text: 'Sign up on SteamGridDB, then select the "Generate API key" button under Preferences -> API.' + + - env_var: SCREENSCRAPER_USER + label: "ScreenScraper user name" + help_text: 'Sign up on screenscraper.fr. Your account name is the API user name.' + + - env_var: SCREENSCRAPER_PASSWORD + label: "ScreenScraper password" + help_text: 'The password of your screenscraper.fr account.' + + - env_var: MOBYGAMES_API_KEY + label: "MobyGames API Key" + help_text: 'Sign up on MobyGames, then ask for a key on the API page. It gives detailed game information and credits.' diff --git a/templates/romm/steps/90dd9d68258286ef.felhom.yml b/templates/romm/steps/90dd9d68258286ef.felhom.yml new file mode 100644 index 0000000..bd459dc --- /dev/null +++ b/templates/romm/steps/90dd9d68258286ef.felhom.yml @@ -0,0 +1,236 @@ +# ============================================================================= +# .felhom.yml — App metadata for felhom-controller +# ============================================================================= + +# --- Display info (shown on dashboard) --- +display_name: "RomM" +description: "Retró játékgyűjtemény kezelő" +category: "media" +subdomain: "arcade" +slug: "romm" +# catalog_since: the date THIS repo last changed this app's pinned images. Any commit that +# changes an image: line must set this to the same day (see CLAUDE.md). +catalog_since: "2026-09-23" + +# --- Resource hints (displayed on deploy screen) --- +resources: + mem_request: "300M" + mem_limit: "1280M" + pi_compatible: false + needs_hdd: true + +# --- Backup classification (referential coupling; see felhom.eu documentation/audits/SPIKE-backup-classification-2026-07-14.md) --- +backup: + userdata: + - path: roms + class: optional # ruled: curated ROM sets often not re-acquirable + hdd: + - path: appdata/romm/resources + class: excluded # scraper cache, re-derivable + +# --- Customer-facing folder annotation (R-75) --- +data_paths: + - path: roms + root: userdata + role: library + label: "ROM gyűjtemény" + +# --- Deploy fields (first deployment only) --- +deploy_fields: + - env_var: DOMAIN + label: "Domain" + type: domain + description: "A szerver domain neve" + locked_after_deploy: true + + - env_var: SUBDOMAIN + label: "Aldomain" + type: subdomain + default: "arcade" + required: true + locked_after_deploy: true + description: "Az alkalmazás aldomainje" + + - env_var: DB_PASSWORD + label: "Adatbázis jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: MYSQL_ROOT_PASSWORD + label: "MariaDB root jelszó" + type: secret + generate: "password:24" + locked_after_deploy: true + + - env_var: ROMM_AUTH_SECRET_KEY + label: "Hitelesítési titkosítási kulcs" + type: secret + generate: "hex:32" + locked_after_deploy: true + + - env_var: HDD_PATH + label: "Adattárolási útvonal" + type: path + required: true + placeholder: "/mnt/felhom-drives/hdd_1" + description: "A külső merevlemez elérési útja, ahol a ROM-ok és borítóképek tárolódnak" + locked_after_deploy: true + +# --- 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: + - "Retró játékgyűjtemény rendszerezése és böngészése webes felületen" + - "Játékok metaadatainak automatikus letöltése — borítók, leírások, értékelések" + - "Platformonkénti szűrés és keresés a teljes gyűjteményben" + - "ROM fájlok webes feltöltése és letöltése" + - "Többfelhasználós hozzáférés a háztartás tagjai számára" + + first_steps: + - "Nyisd meg az arcade.DOMAIN címet a böngészőben" + - "Jelentkezz be az alapértelmezett admin / admin fiókkal" + - "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" + - "Opcionális: állíts be metaadat-szolgáltatókat a borítóképek és leírások automatikus letöltéséhez (lásd lent)" + + prerequisites: + - "Külső HDD szükséges a ROM fájlok és borítóképek tárolásához" + - "Legalább 1 GB szabad RAM ajánlott (MariaDB + Redis + RomM)" + - "ROM fájlok platform mappákba rendezve (pl. roms/gba/, roms/snes/)" + +# --- Optional config (configurable before or after deployment) --- +optional_config: + - group: "Metaadat-szolgáltatók" + description: "Játékok borítóinak, leírásainak és értékeléseinek automatikus letöltéséhez. Legalább az IGDB beállítása ajánlott. Mindegyik ingyenesen használható regisztráció után." + fields: + - env_var: IGDB_CLIENT_ID + label: "IGDB Client ID" + type: text + help_url: "https://api-docs.igdb.com/#getting-started" + help_text: "1) Regisztrálj / jelentkezz be a Twitch fejlesztői portálon (dev.twitch.tv). 2) Hozz létre egy új alkalmazást (bármilyen névvel). 3) Másold be a Client ID-t." + + - env_var: IGDB_CLIENT_SECRET + label: "IGDB Client Secret" + type: secret_input + help_text: "A Twitch alkalmazásod Client Secret-je (a „New Secret\" gombbal generálhatod)." + + - env_var: STEAMGRIDDB_API_KEY + label: "SteamGridDB API Key" + type: text + help_url: "https://www.steamgriddb.com/profile/preferences/api" + help_text: "Regisztrálj a SteamGridDB oldalon, majd a Preferences → API fül alatt kattints a „Generate API key\" gombra." + + - env_var: SCREENSCRAPER_USER + label: "ScreenScraper felhasználónév" + type: text + help_url: "https://www.screenscraper.fr/" + help_text: "Regisztrálj a screenscraper.fr oldalon. A felhasználóneved lesz az API felhasználónév." + + - env_var: SCREENSCRAPER_PASSWORD + label: "ScreenScraper jelszó" + type: secret_input + help_text: "A screenscraper.fr fiókod jelszava." + + - env_var: MOBYGAMES_API_KEY + label: "MobyGames API Key" + type: text + help_url: "https://www.mobygames.com/info/api/" + help_text: "Regisztrálj a MobyGames oldalon, majd az API oldalon igényelj kulcsot. Részletes játékinformációkat és krediteket biztosít." + +# --- Controller-side health probe --- +healthcheck: + checks: + - type: http + port: 8080 + +# --- English copy (localisation slice 5, R-560) -------------------------------------------- +# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing +# field shows the Hungarian one; a controller older than 0.257.0 ignores the block entirely. +i18n: + en: + description: "Retro game collection manager" + + data_paths: + - path: roms + label: "ROM collection" + + deploy_fields: + - env_var: DOMAIN + label: "Domain" + description: "The server domain name" + + - env_var: SUBDOMAIN + label: "Subdomain" + description: "The subdomain this app answers on" + + - env_var: DB_PASSWORD + label: "Database password" + + - env_var: MYSQL_ROOT_PASSWORD + label: "MariaDB root password" + + - env_var: ROMM_AUTH_SECRET_KEY + label: "Sign-in encryption key" + + - env_var: HDD_PATH + label: "Data storage path" + placeholder: "/mnt/felhom-drives/hdd_1" + description: "The path to the external hard drive where the ROMs and cover art are kept" + + 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" + - "Game details download themselves - cover art, descriptions, ratings" + - "Filter and search the whole collection by platform" + - "Upload and download ROM files in your browser" + - "Several people in the household can have their own account" + + first_steps: + - "Open arcade.DOMAIN in your browser" + - "Sign in with the default admin / 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" + - "Optional: set up metadata providers so cover art and descriptions download themselves (see below)" + + prerequisites: + - "An external hard drive is needed to keep the ROM files and cover art on" + - "At least 1 GB of free RAM is recommended (MariaDB + Redis + RomM)" + - "ROM files sorted into platform folders (for example roms/gba/, roms/snes/)" + + optional_config: + - match_group: "Metaadat-szolgáltatók" + group: "Metadata providers" + description: "So that cover art, descriptions and ratings download themselves. IGDB is the one worth setting up first. All of them are free after you sign up." + fields: + - env_var: IGDB_CLIENT_ID + label: "IGDB Client ID" + help_text: '1) Sign up or sign in on the Twitch developer portal (dev.twitch.tv). 2) Create a new application (any name will do). 3) Copy the Client ID across.' + + - env_var: IGDB_CLIENT_SECRET + label: "IGDB Client Secret" + help_text: 'The Client Secret of your Twitch application (the "New Secret" button makes one).' + + - env_var: STEAMGRIDDB_API_KEY + label: "SteamGridDB API Key" + help_text: 'Sign up on SteamGridDB, then select the "Generate API key" button under Preferences -> API.' + + - env_var: SCREENSCRAPER_USER + label: "ScreenScraper user name" + help_text: 'Sign up on screenscraper.fr. Your account name is the API user name.' + + - env_var: SCREENSCRAPER_PASSWORD + label: "ScreenScraper password" + help_text: 'The password of your screenscraper.fr account.' + + - env_var: MOBYGAMES_API_KEY + label: "MobyGames API Key" + help_text: 'Sign up on MobyGames, then ask for a key on the API page. It gives detailed game information and credits.'