READ-ONLY STUDY. No code, no version, no image, no golden. No delete verb was issued against any live store. ep0, DooPlex and Peti's box were not touched at all. Q1 FIRST, AND IT DID NOT GO THE EXPECTED WAY. The brief supposed a working seven-day snapshot net might bound the worst case. Measured on BOTH boxes over their own SFTP credential, with a positive and a negative control on each: NO .snapshots is visible to either sub-account - not in the account home, not inside the repo - and the account is jailed at /. Either none exist or a sub-account cannot see them, and the second is not a reprieve: a snapshot the box cannot see is one the box cannot restore from, so recovery would be an operator act at the Hetzner panel. The register's claim rests on nothing that was checked. The row has NO R-number, so nothing can cite it; its "confirm tomorrow" was 2026-07-27, 36 days ago; and the DUE-CHECKS block built for exactly this (R-341) is EMPTY. R-95's word "ARMED" is withdrawn pending R-429. The confirming field is a Hetzner API field, so this spike STOPPED at the section 11-D fence and left it for Viktor - ten minutes in the panel, and it re-ranks everything. Q2: TEN verbs, not nine. `check` was missing from the brief's list; `dump` is not a verb (it is a progress phase constant) and was withdrawn. There are TWO `forget --prune` sites - offbox.go:1388 AND offbox.go:1759 - and disarming one without the other reproduces R-191 exactly. Q3 (documented, from our own API mirror): AccessSettings has five booleans and `readonly` is the only permission axis. No append-only. So the PBS shape does NOT transfer - PBS is a server that can refuse; a Storage Box is a filesystem that runs nothing. Q5 (measured, faithful append-only model, both controls passed first): withdrawing delete does NOT wedge the store - restic treats a dead owner's lock as stale and proceeds. The constraint everyone feared is not the blocker. But `unlock --remove-all` printed "successfully removed locks" while the lock was still there, and resticStep's crash-lock self-heal is built on that call - R-430. Q6 (measured, with a control): restic 0.14.0 DOES speak rest:. Append-only is a rest-server flag, not a restic one. Q7 (measured): detection is nearly free. snapshot_count already reaches the hub and the hub APPENDS reports, so the history to compare against is already on disk. RECOMMENDATION: answer Q1 today (Viktor, ten minutes), then build detection, then move retention off the box. Defer the transport change until Q1 is answered. Register: OPEN 179 -> 181. Filed R-429, R-430; R-95 updated and kept OPEN. 07 row 10's status is deliberately UNCHANGED.
felhom.eu
Website, manifests, and infrastructure for Felhőm.eu — a managed home-server service for Hungarian households.
Overview
This repository contains:
- Website (
website/) — Static HTML pages served at felhom.eu - Kubernetes manifests (
manifests/) — All k3s deployments for the felhom.eu ecosystem - Assets (
website/assets/) — Logo, images, OG images
The website runs on a single-node k3s cluster alongside the rest of the Felhőm management infrastructure (Healthchecks, Umami analytics, contact mailer).
Branding
| Aspect | Value |
|---|---|
| Brand name | Felhőm.eu (with accent: ő) |
| Domain | felhom.eu (without accent — domain limitation) |
| Tagline | „Saját felhőd, saját szabályaid" |
| Controller product | Felhő Felügyelő (customer-facing name) |
| Controller code name | felhom-controller (backend/repo/container) |
| Language | Hungarian throughout all customer-facing content |
| Contact email | info@felhom.eu |
| Admin email | admin@felhom.eu |
Why "Felhőm"?
"Felhő" means "cloud" in Hungarian. The "m" suffix makes it possessive — "my cloud" (felhőm). The .eu domain is part of the brand identity and appears in the logo. The double meaning of "felhő" (tech cloud + weather cloud) is intentional and used in product naming (e.g., Felhő Felügyelő = "Cloud Supervisor/Inspector").
Website Pages
| File | URL | Purpose |
|---|---|---|
index.html |
/ |
Landing page — hero, services, app preview, backup intro, contact |
alkalmazasok.html |
/alkalmazasok |
Full application catalog (45+ apps with categories) |
technologiak.html |
/technologiak |
Technology stack explanation (Docker, Felhő Felügyelő, Proxmox, Kubernetes) |
biztonsagimentes.html |
/biztonsagimentes |
Backup strategy — 3-2-1 rule, monitoring, restore procedures |
gyik.html |
/gyik |
FAQ — structured Q&A with JSON-LD schema |
kapcsolat.html |
/kapcsolat |
Contact form + email, sends via contact-mailer API |
szolgaltatasok-nonpublic.html |
/szolgaltatasok-nonpublic |
Pricing/services page (not linked in nav, robots disallowed) |
All pages use:
- Clean URLs — nginx serves
.htmlfiles without extension (/gyik→gyik.html) - Unified CSS — each page contains the full CSS (no external stylesheet, for simplicity)
- Responsive design — mobile hamburger menu, responsive grids
- UTF-8 with BOM — all HTML files are saved as UTF-8-BOM for Hungarian character support
- Umami analytics — privacy-friendly tracking script on every page
Infrastructure
Architecture
Internet
│
▼
Cloudflare (DNS only, no proxy)
│
▼ CNAME → dooplex.hopto.org
│
Home network (dynamic IP via No-IP DynDNS)
│
▼ Port forward 80/443
│
k3s cluster (single node)
├── nginx-ingress (TLS termination via cert-manager + Let's Encrypt)
│
├── felhom-system namespace:
│ ├── felhom-webpage (nginx + git-sync sidecar)
│ ├── filebrowser (files.felhom.eu — website file management)
│ ├── contact-mailer (Go app — /api/contact endpoint)
│ ├── umami + umami-db (stats.felhom.eu — web analytics)
│ └── healthchecks (status.felhom.eu — monitoring)
│
└── cert-manager (letsencrypt-prod cluster issuer)
Kubernetes Manifests
| Manifest | Services | Subdomains |
|---|---|---|
webpage.yaml |
nginx (website), FileBrowser, git-sync | felhom.eu, www.felhom.eu, files.felhom.eu |
contact-mailer.yaml |
Go HTTP server for contact form | felhom.eu/api/* (path-based routing) |
umami.yaml |
Umami v3 + PostgreSQL | stats.felhom.eu |
healthchecks.yaml |
Healthchecks | status.felhom.eu |
Website Deployment
The website uses a git-sync sidecar pattern:
git-synccontainer polls this repository (sparse checkout:/website/only)- Syncs to a shared
emptyDirvolume nginxcontainer serves from the synced content- Changes pushed to this repo are live within minutes (no manual deployment)
FileBrowser at files.felhom.eu provides a web UI for quick edits to website files (emergency fixes, asset uploads) without needing git. It writes to a Longhorn PVC that the website nginx also reads from.
Storage
All persistent data uses Longhorn distributed storage:
filebrowser-files(1Gi, ReadWriteMany) — website filesfilebrowser-db(100Mi) — FileBrowser SQLite databaseumami-db-data(2Gi) — Umami PostgreSQL datahealthchecks-data(1Gi) — Healthchecks SQLite data
DNS Configuration (Cloudflare)
Domain: felhom.eu — Cloudflare DNS (free plan), DNS only mode (no proxy/orange cloud).
Records
| Type | Name | Content | Notes |
|---|---|---|---|
| CNAME | felhom.eu |
dooplex.hopto.org | Main website |
| CNAME | www |
dooplex.hopto.org | www redirect |
| CNAME | files |
dooplex.hopto.org | FileBrowser |
| CNAME | stats |
dooplex.hopto.org | Umami analytics |
| CNAME | status |
dooplex.hopto.org | Healthchecks |
| CNAME | ntfy |
dooplex.hopto.org | Push notifications |
| MX | felhom.eu |
route{1,2,3}.mx.cloudflare.net | Incoming email → Cloudflare Email Routing |
| MX | send |
feedback-smtp.eu-west-1.amazonses.com | Resend sending domain |
| TXT | felhom.eu |
v=spf1 include:_spf.mx.clo... |
SPF for Cloudflare |
| TXT | send |
v=spf1 include:amazonses... |
SPF for Resend |
| TXT | cf2024-1._domainkey |
DKIM for Cloudflare Email Routing | |
| TXT | resend._domainkey |
DKIM for Resend | |
| TXT | _dmarc |
v=DMARC1; p=none; |
DMARC policy |
| TXT | felhom.eu |
google-site-verification=... |
Google Search Console |
Incoming Email
Cloudflare Email Routing (free) handles all incoming mail:
info@felhom.eu→ forwarded to personal Gmailadmin@felhom.eu→ forwarded to personal Gmail- Catch-all → not configured
Outgoing Email (Transactional)
Resend (free tier) handles outgoing email via API:
- Contact form submissions → sends formatted email to
info@felhom.eu - Healthchecks alerts → sends to
admin@felhom.eu - Sending domain:
send.felhom.eu(verified with SPF, DKIM) - From address:
Felhom.eu <info@felhom.eu>
Contact Form Flow
- User fills form on
/kapcsolat - JavaScript POST to
/api/contact contact-mailer(Go, in k3s) validates + calls Resend API- Email delivered to
info@felhom.euvia Resend → Cloudflare Email Routing → Gmail
SEO
Google Search Console
- Property:
https://felhom.eu - Verified via DNS TXT record
- Sitemap submitted:
https://felhom.eu/sitemap.xml - 7 pages indexed (all public pages)
On-Page SEO
Every page includes:
<title>with Hungarian keywords + brand<meta name="description">with unique content per page<meta name="keywords">with relevant Hungarian terms<link rel="canonical">to prevent duplicate content- Open Graph tags (og:title, og:description, og:image, og:locale=hu_HU)
- Twitter Card tags (summary_large_image)
- JSON-LD structured data (LocalBusiness on index, Article on technologiak, FAQPage on gyik)
Technical SEO
robots.txt— allows all, disallows/szolgaltatasok-nonpublic, includes sitemap URLsitemap.xml— lists all 6 public pages with priority + changefreq- Clean URLs (no
.htmlextensions) - Static asset caching (7 day expiry for CSS/JS/images)
- Security headers (X-Frame-Options, X-Content-Type-Options)
Analytics
Umami v3 (self-hosted, privacy-focused):
- Dashboard:
https://stats.felhom.eu - Tracking script:
<script defer src="https://stats.felhom.eu/script.js" data-website-id="d419db57-..."> - Cookie-free, GDPR compliant — no consent banner needed
- Backend: dedicated PostgreSQL instance in k3s
Monitoring
Healthchecks (self-hosted):
- Dashboard:
https://status.felhom.eu - Monitors backup jobs, service health
- Sends email alerts via Resend when checks fail
Development Workflow
Quick content edits
- Log into FileBrowser at
https://files.felhom.eu - Edit HTML files directly
- Changes are live immediately
Standard workflow
- Clone this repo from Gitea (
gitea.dooplex.hu) - Edit files locally
- Push to
mainbranch git-syncsidecar picks up changes automatically (~1-2 min)
Adding a new page
- Create
website/newpage.html(copy structure from existing page) - Add to navigation in all pages'
<nav>section - Add to
sitemap.xmlwith appropriate priority - Push — clean URLs handle
/newpageautomatically
Related Repositories
| Repository | Purpose |
|---|---|
| app-catalog-felhom.eu | Docker Compose templates + .felhom.yml metadata for 45+ apps |
| felhom-controller | felhom-controller Go app + customer deploy scripts |
| deploy-portainer | Legacy — Portainer-based deploy scripts (deprecated) |
| homelab-manifests | k3s cluster manifests for dooplex.hu services |
| misc-scripts | Utility scripts (collect-repos.sh, etc.) |
File Encoding
All HTML files in website/ are UTF-8 with BOM (byte order mark). This ensures proper Hungarian character rendering (á, é, í, ó, ö, ő, ú, ü, ű) across all tools and platforms. The BOM is the 3-byte sequence EF BB BF at the start of each file.
When editing files, ensure your editor preserves UTF-8-BOM encoding. VS Code: check "UTF-8 with BOM" in the bottom status bar.