# Felhom App Catalog Central repository for all Felhom customer application deployments. ## Architecture ``` felhom-app-catalog/ ├── templates/ # Docker Compose templates ({{DOMAIN}} placeholder) │ ├── actualbudget/ │ ├── docmost/ │ ├── filebrowser/ │ ├── homebox/ │ ├── immich/ │ ├── mealie/ │ ├── romm/ │ ├── stirling-pdf/ │ └── vaultwarden/ ├── customers/ # Per-customer configuration │ ├── demo-felhom.yaml │ └── pi-customer-1.yaml ├── scripts/ │ └── render.sh # Renders customer repos from templates └── README.md ``` ## How It Works 1. **Templates** contain Docker Compose files with `{{DOMAIN}}` and `{{HDD_PATH}}` placeholders 2. **Customer configs** define which apps each customer gets, their domain, HDD path, and any version overrides 3. **render.sh** generates per-customer Gitea repos with all placeholders substituted 4. **Portainer GitOps** on each customer node pulls from their repo and deploys ### Placeholder Reference | Placeholder | Source | Example | |-------------|--------|---------| | `{{DOMAIN}}` | `domain:` in customer YAML | `demo-felhom.eu` | | `{{HDD_PATH}}` | `hdd_path:` in customer YAML | `/mnt/hdd_1` | ### Storage Strategy - **HDD host paths** (`{{HDD_PATH}}/storage/...`): Large user data — photos, documents, ROMs - **Named Docker volumes** (on NVMe): Databases, app config, caches — need fast I/O - Templates that don't use `{{HDD_PATH}}` work without it (e.g. ActualBudget, Mealie) ## Workflow ### Adding a new app to the catalog 1. Create `templates//docker-compose.yml` using `{{DOMAIN}}` placeholder 2. Add to relevant customer configs in `customers/` 3. Run `./scripts/render.sh` to regenerate customer repos ### Updating an app version 1. Edit the image tag in `templates//docker-compose.yml` 2. Run `./scripts/render.sh` — skips customers with version overrides 3. Portainer auto-detects git changes and redeploys (if polling enabled) ### Adding a new customer 1. Create `customers/.yaml` 2. Create the Gitea repo: `customers/-stacks` 3. Run `./scripts/render.sh --customer ` 4. Set up Portainer GitOps stacks on the customer node ## Portainer Stack Setup (per app) On the customer's Portainer: 1. **Stacks → Add Stack → Repository** 2. Repository URL: `https://gitea.felhom.eu/customers/-stacks` 3. Compose path: `/docker-compose.yml` 4. Add environment variables (secrets — DB passwords, API keys, etc.) 5. Enable **GitOps auto-update** (optional, 5-minute polling) 6. Deploy ## Environment Variables Secrets are **never stored in Git**. They live in Portainer's stack environment variables on each customer node. Each template documents required env vars in comments at the top of the compose file. ## Version Pinning In a customer YAML, you can pin specific app versions: ```yaml overrides: immich_version: "v2.4.1" # Don't auto-update Immich for this customer auto_update: false # Skip ALL updates for this customer ``` ## App Catalog | App | DB Type | RAM | Pi | HDD Data | Subdomain | |-----|---------|-----|-----|----------|-----------| | ActualBudget | None (file) | ~50MB | ✅ | — | budget.* | | Docmost | PostgreSQL + Redis | ~200MB | ⚠️ | — | docs.* | | FileBrowser | None (file) | ~30MB | ✅ | `{{HDD_PATH}}/` | files.* | | Homebox | None (SQLite) | ~50MB | ✅ | — | inventory.* | | Immich | PostgreSQL + Redis | ~4GB | ❌ | `{{HDD_PATH}}/storage/immich/` | photos.* | | Mealie | None (SQLite) | ~200MB | ✅ | — | recipes.* | | Paperless-ngx | PostgreSQL + Redis | ~500MB | ✅ | `{{HDD_PATH}}/storage/paperless/` | paperless.* | | ROMM | MariaDB + Redis | ~300MB | ⚠️ | `{{HDD_PATH}}/storage/romm/` | arcade.* | | Stirling-PDF | None | ~200MB | ✅ | — | pdf.* | | Vaultwarden | None (SQLite) | ~50MB | ✅ | — | vault.* |