vault backup: 2026-04-28 21:49:41

This commit is contained in:
Vadym Samoilenko 2026-04-28 21:49:41 +01:00
parent dd92493a35
commit 1cd515b382
5 changed files with 255 additions and 1 deletions

View file

@ -23,7 +23,7 @@ This 3-hop pattern works for hundreds of articles without vector search.
| [[wiki/tech-patterns/_index\|tech-patterns/]] | Recurring tech stacks: FastAPI, React/Vite, Next.js, Azure AD, AI, Box, One2Edit, Redis/Celery, cost-tracker | 13 |
| [[wiki/architecture/_index\|architecture/]] | Cross-cutting architectural patterns: Docker Compose, multi-agent AI, GCP timeout, RAG, hotfolder, optical-dev deploy, cost-tracker, new-project checklist, troubleshooting playbooks, ADR log | 10 |
| [[wiki/client-knowledge/_index\|client-knowledge/]] | Per-client notes for Ford, H&M, L'Oréal, Barclays, Ferrero, 3M | 6 |
| [[wiki/concepts/_index\|concepts/]] | Atomic knowledge extracted from Claude Code sessions | 45 |
| [[wiki/concepts/_index\|concepts/]] | Atomic knowledge extracted from Claude Code sessions | 47 |
| [[wiki/connections/_index\|connections/]] | Cross-cutting insights linking 2+ concepts: FastAPI+Azure AD+Docker trinity, AI→cost-tracker, Apache+Vite basePath, GCP→REST polling, Box+hotfolder | 8 |
| [[wiki/qa/_index\|qa/]] | Filed answers to queries (saved with `--file-back`) | 0 |
| [[wiki/homelab/_index\|homelab/]] | Self-hosted infra: Proxmox install, IOMMU/PCI passthrough, hypervisor setup, budget builds, HP Elitedesk G3, Homarr API + Apps + Boards + Certificates + Integrations + Settings + Tasks + AdGuard + Clock + Docker Stats + Docker Integration + Download Client + Firewall + Proxmox Integration + Radarr + Readarr + Sonarr + Bookmarks + Calendar + Icons + App Widget + Weather + GitHub + Nextcloud + qBittorrent + RSS Feed + Speedtest Tracker + System Health Monitoring + System Resources + Services Map + Media Stack | 38 |

View file

@ -50,6 +50,8 @@
| [[wiki/concepts/lazy-user-mirror]] | User mirror created on first AI event, not on user creation — minimal integration surface, source project stays owner | ai-cost-tracker | 2026-04-27 |
| [[wiki/concepts/sync-with-outbox]] | Sync HTTP + SQLite outbox: record() never blocks the AI pipeline; background flusher retries up to 10x | ai-cost-tracker | 2026-04-27 |
| [[wiki/concepts/litellm-pricing-source]] | LiteLLM model_prices JSON as auto-updating LLM price source — why scraping provider sites is fragile | ai-cost-tracker | 2026-04-27 |
| [[wiki/concepts/authentik-homelab-tradeoffs]] | Authentik v2026.2.2 migration failure `0056`, ~500MB RAM overhead, NPM auth_request removal — when to keep vs remove | daily/2026-04-27.md | 2026-04-27 |
| [[wiki/concepts/icloud-git-sync-conflict]] | iCloud creates `main 2` files in `.git/refs/heads/` on sync conflict — causes `badRefName`; fix and prevention | daily/2026-04-27.md | 2026-04-27 |
<!-- Articles added automatically by compile.py -->
<!-- Format: | [[concepts/slug]] | One-line summary | daily/YYYY-MM-DD.md | date | -->

View file

@ -0,0 +1,106 @@
---
title: "Authentik — Homelab Trade-offs and When to Remove It"
aliases: [authentik-homelab, authentik-sso, authentik-removal, authentik-npm-auth]
tags: [authentik, homelab, sso, npm, proxmox, lxc, selfhosted, security]
sources:
- "daily/2026-04-27.md"
created: 2026-04-27
updated: 2026-04-27
---
# Authentik — Homelab Trade-offs and When to Remove It
Authentik is an open-source identity provider that adds SSO, OAuth2, and forward-proxy authentication to self-hosted services. In a homelab context it requires ~500 MB RAM and has a complex multi-container stack (server + worker + PostgreSQL + Redis). It is only worth running if SSO is genuinely configured for each service it protects — if services fall back to their native login pages, Authentik adds overhead without meaningful security benefit.
## Key Points
- **Authentik v2026.2.2 broke on migration `0056`** — the field `Role.filter(group_id=...)` was renamed; upgrading from an older version triggers this migration failure and prevents the stack from starting
- **RAM overhead: ~500 MB** per running instance — significant in a homelab with limited RAM (68 GB total)
- **Authentik is only justified if SSO is configured per service** — if protected services still show their own login form via NPM's `auth_request`, Authentik provides minimal protection
- **NPM `auth_request` removal** is the critical step when decommissioning — every proxy host that had Authentik auth must be individually updated; forget one and it blocks the service
- **Native service logins (Dozzle, AdGuard, Backrest, IT-Tools, Uptime Kuma) are sufficient** for homelab services accessible only via VPN or internal DNS
## Details
### The Migration Failure (v2026.2.2)
Authentik 2026.2.2 introduced an ORM change that renamed a Role filter field. On first startup after upgrade, Django migrations run automatically — migration `0056` fails because the old field name no longer exists in the codebase, but the migration assumes it does.
```
authentik-server | django.db.utils.ProgrammingError: column "group_id" does not exist
authentik-server | Error occurred during database migration — aborting startup
```
The stack cannot start in this state. Options:
1. Downgrade Authentik to the last working version before `0056`
2. Restore from a database backup taken before the upgrade
3. Remove Authentik entirely if the SSO value doesn't justify the repair effort
### Decision Criteria: Keep vs Remove
| Condition | Keep Authentik | Remove Authentik |
|-----------|---------------|-----------------|
| SSO configured in each protected service | ✓ | — |
| Services support OIDC natively | ✓ | — |
| Multiple users with different access levels | ✓ | — |
| Services fall back to native login via `auth_request` | — | ✓ |
| Only 12 users (homelab owner) | — | ✓ |
| RAM is constrained (<8 GB total) | | |
| Services accessible only via VPN/internal DNS | — | ✓ |
For a single-user homelab where services are accessible only via Tailscale VPN or internal DNS, native service logins provide adequate security without the complexity of an identity provider.
### NPM `auth_request` Removal
When Authentik protects services via Nginx Proxy Manager's forward-proxy auth feature, each proxy host has an extra configuration block pointing to Authentik's outpost URL. Removing Authentik requires visiting each protected proxy host in NPM and disabling `auth_request`:
**NPM Proxy Host → Advanced Tab → Custom Nginx Configuration** — remove the block similar to:
```nginx
auth_request /akprox/auth/nginx;
error_page 401 = @akprox-signin;
location @akprox-signin {
return 302 https://auth.internal.domain/akprox/sign_in?rd=$scheme://$http_host$request_uri;
}
```
This must be done for every protected proxy host — if missed, NPM attempts to reach Authentik's outpost (which no longer exists) and returns 401 for all requests to that service. Services affected in the 2026-04-27 removal: AdGuard, Backrest, Actual Budget, IT-Tools, Uptime Kuma — 5 services across 9 NPM proxy hosts with the configuration.
### Dozzle Native Auth Fallback
Dozzle (a Docker container log viewer) was previously behind Authentik forward-proxy auth without its own login. When Authentik is removed, Dozzle becomes unauthenticated. The fix: enable Dozzle's built-in user authentication.
In Dozzle's Docker Compose environment:
```yaml
services:
dozzle:
environment:
DOZZLE_AUTH_PROVIDER: simple
volumes:
- ./users.yml:/data/users.yml
```
`users.yml` defines users and bcrypt-hashed passwords. This replaces the Authentik forward-proxy with Dozzle's own session management.
### Authentik vs Simpler Alternatives
For homelab SSO that is lighter than Authentik:
| Solution | RAM | Complexity | OIDC | Forward Proxy |
|----------|-----|------------|------|---------------|
| Authentik | ~500 MB | High | ✓ | ✓ |
| Authelia | ~50 MB | Medium | ✓ | ✓ |
| Pocket ID | ~20 MB | Low | ✓ (limited) | ✗ |
| Native logins | 0 MB overhead | None | — | — |
Authelia is the recommended replacement if centralized auth is still needed — significantly lighter RAM footprint, simpler stack (no separate worker process), and still supports forward-proxy authentication with NPM.
## Related Concepts
- [[wiki/concepts/homarr-proxmox-integration]] — Homarr and NPM configuration in the same homelab
- [[wiki/concepts/adguard-dns-rewrites-homelab]] — internal DNS for homelab services that Authentik was protecting
- [[wiki/concepts/proxmox-container-502-misdiagnosis]] — 502 errors from NPM are similar to what happens when auth_request misconfigured
- [[wiki/concepts/tailscale-dns-homelab]] — the VPN layer that provides access control without an identity provider
## Sources
- [[daily/2026-04-27.md]] — Authentik 2026.2.2 failed on migration `0056`; decided to remove rather than repair; `auth_request` removed from all 9 NPM proxy hosts; Dozzle switched to native simple auth; 5 services now use their own logins

View file

@ -0,0 +1,141 @@
---
title: "iCloud Sync — Git Repository Corruption via Conflict Files"
aliases: [icloud-git-conflict, icloud-obsidian-git, git-badrefname-icloud, icloud-git-sync]
tags: [icloud, git, obsidian, sync, homelab, dotfiles, conflict]
sources:
- "daily/2026-04-27.md"
created: 2026-04-27
updated: 2026-04-27
---
# iCloud Sync — Git Repository Corruption via Conflict Files
iCloud Drive creates conflict copies of files by appending a space and number to the filename (e.g., `main 2`, `ORIG_HEAD 2`) when two devices have modified the same file simultaneously. If the `.git/` directory of a repository is stored inside an iCloud-synced folder, these conflict files appear inside `.git/refs/heads/` and git fails with `fatal: 'badRefName'` because git ref names cannot contain spaces. The repository becomes unusable until the conflict files are removed manually.
## Key Points
- **iCloud conflict file naming**: when a sync conflict occurs, iCloud creates `original_name 2` (space + number) in the same directory — this is not user-visible in Finder but exists on the filesystem
- **`.git/refs/heads/main 2`** is an invalid git ref name — git rejects any ref containing a space; `git status`, `git log`, and `git pull` all fail with `fatal: bad ref 'main 2'`
- **Root cause**: two devices with an Obsidian vault (or any git repo) open simultaneously editing the same files — when both commit and iCloud syncs, diverged histories create a conflict in `.git/refs/heads/`
- **Fix**: delete all `* 2` files from `.git/refs/heads/`, then merge the diverged histories with `git merge`
- **Prevention**: either exclude `.git/` from iCloud sync, keep Obsidian open on only one device at a time, or use Obsidian Sync instead of git
## Details
### How the Corruption Happens
The sequence that leads to this state:
1. Vault is open on Device A (Mac) and Device B (iPhone/iPad) simultaneously
2. Both devices make changes that result in different git commits (Device A via shell, Device B via Obsidian's git plugin)
3. iCloud syncs `.git/refs/heads/main` from both devices — they have different SHA hashes
4. iCloud detects a conflict and creates `.git/refs/heads/main 2` alongside the original `.git/refs/heads/main`
5. When either device runs any git command, git enumerates refs, encounters `main 2`, and fails:
```
fatal: 'refs/heads/main 2' is not a valid ref name
```
Git's ref naming rules prohibit spaces (and several other characters) — this is enforced at the filesystem level in `git check-ref-format`. A space in a ref name is unconditionally rejected.
### Diagnosing the Problem
```bash
# Inside the git repo (.git is the vault's .git directory)
git status
# fatal: 'refs/heads/main 2' is not a valid ref name
# Find all iCloud conflict files in .git
find .git/refs -name "* 2" -o -name "*ORIG*"
# .git/refs/heads/main 2
# .git/refs/heads/ORIG_HEAD 2 (sometimes, if a merge was in progress)
# Check if history has diverged
git log --oneline --graph --all
# Shows two branches diverging at a common ancestor
```
### The Fix
```bash
# Step 1: Remove iCloud conflict files
rm ".git/refs/heads/main 2"
rm ".git/refs/heads/ORIG_HEAD 2" # if present
# Step 2: Verify git is functional again
git status
# Will show: "Your branch and 'origin/main' have diverged"
# Step 3: Merge the diverged histories
git merge origin/main
# Or if origin/main was the "other" device's version:
git pull --no-rebase
# Step 4: Resolve any content conflicts (if files were edited on both devices)
# git will report conflicted files if any
# Edit them to resolve, then:
git add .
git commit -m "Merge diverged device histories"
# Step 5: Push
git push
```
If `ORIG_HEAD` also has a conflict copy, git may be in an interrupted merge state. Check:
```bash
git status
# "You have unmerged paths" → resolve conflicts and commit
# Or abort: git merge --abort
```
### Prevention Options
**Option 1: Exclude `.git/` from iCloud sync**
Add a `.nosync` extension or use an iCloud exclusion mechanism:
```bash
# Rename .git directory to bypass iCloud (not recommended — breaks git)
# Better: move the entire repo outside iCloud Drive
# For Obsidian vault: keep vault in iCloud but move .git outside
# (Not straightforward with standard git)
```
The cleanest solution for Obsidian: store the vault in iCloud (for Obsidian's own sync of notes) but use **Obsidian Sync** (Obsidian's paid service) instead of git for device sync.
**Option 2: Use Obsidian Sync instead of git-based sync**
Obsidian Sync handles device conflicts at the application level — it understands markdown notes and syncs them without creating filesystem-level conflicts. Downside: costs $10/month. Upside: no git conflict corruption possible.
**Option 3: Single commit source**
Designate one device as the git commit device (e.g., only the Mac commits). Other devices open the vault read-only or in Obsidian without the git plugin active. iCloud still syncs the files, but only one device creates git commits — no diverged histories.
**Option 4: `.gitignore`-based partial solution**
Cannot ignore `.git/` itself (git always tracks `.git/`), but can exclude files that iCloud conflict-copies more aggressively:
```bash
# This does NOT help — git itself needs .git/refs/heads/main
# and cannot ignore files in its own metadata directory
```
This option doesn't work — the `.git/` directory is not tracked by git and cannot be gitignored; iCloud syncs it regardless.
### Obsidian + iCloud + Git Compatibility Matrix
| Setup | Risk | Notes |
|-------|------|-------|
| Obsidian Sync only (no git) | Low | Paid; no conflict files in `.git/` |
| git in iCloud vault, single device | Low | No simultaneous edits |
| git in iCloud vault, 2+ devices | High | Conflict files in `.git/` on simultaneous edits |
| git repo outside iCloud | None | Vault not synced by iCloud |
| iCloud vault + Obsidian git plugin + 2 devices | Very high | Both git and iCloud create conflicts |
## Related Concepts
- [[wiki/concepts/memory-compiler-mac-migration]] — Obsidian vault and git repository migration context
- [[wiki/concepts/git-includeif-per-remote]] — git configuration for multiple identities across repos
- [[wiki/concepts/fish-fisher-conf-d-conflict]] — similar "file managed by tool X corrupted by external copy" pattern (Fisher vs manual conf.d copy)
## Sources
- [[daily/2026-04-27.md]] — Obsidian vault git repo on iCloud failed with `badRefName`; root cause was iCloud creating `main 2` and `ORIG_HEAD 2` in `.git/refs/heads/` after simultaneous edits on two devices; fix was deleting conflict files and merging diverged histories; lesson: don't keep vault open on two devices simultaneously with git sync

View file

@ -99,3 +99,8 @@
- Articles created: (none)
- Articles updated: (none)
- Note: No sessions in daily log; memory flush failed with FLUSH_ERROR (exit code 1) — no knowledge to extract
## [2026-04-28T21:46:04+01:00] compile | 2026-04-27.md
- Source: daily/2026-04-27.md
- Articles created: [[wiki/concepts/authentik-homelab-tradeoffs]], [[wiki/concepts/icloud-git-sync-conflict]]
- Articles updated: [[wiki/concepts/_index]] (concepts 45→47), [[wiki/_master-index]] (concepts 45→47)