--- okf: "0.1" type: decision visibility: private status: active updated: 2026-07-09 links: - ../services/gokapi.md - ../runbooks/gokapi-cutover.md --- # Gokapi — decyzje: storage, szyfrowanie E2E, siec ## Storage — lokalny dysk VPS (nie S3) Decyzja Oskara: bez S3, dysk lokalny VPS. VPS ma tylko 80 GB SSD dzielone z npm/outline/joplin/ai-cluster/fleet-prometheus — więc **ograniczenia rozmiaru + brak globalnego domyślnego expiry to jedyna ochrona dysku**: - `GOKAPI_MAX_FILESIZE=5120` (5 GB/plik; upstream default to 100 GB — za dużo na ten dysk). - `GOKAPI_MIN_FREE_SPACE=2048` (2 GB headroom zanim Gokapi odmówi uploadu; upstream default 400 MB, za mało przy dzielonym dysku). - **Gokapi NIE MA globalnego domyślnego expiry/limitu pobrań** — to wybór per-upload w formularzu web. Nie da się tego wymusić przez env var ani config. Praktyka: przy każdym uploadzie ustawiać rozsądne wartości (np. **7 dni / 10 pobrań**), żeby wygasające linki faktycznie czyściły dysk. ## Szyfrowanie E2E — WŁĄCZONE (decyzja Oskara) Gokapi ma 3 poziomy szyfrowania (żaden / lokalny / **end-to-end**). Wybór robi się w kroku "Encryption" wizardu `/setup` przy pierwszym starcie — nie ma env vara. Level 3 (E2E) = plik szyfrowany w przeglądarce przed uploadem, serwer nigdy nie widzi treści w plaintext. Uwaga upstream: implementacja szyfrowania nie była niezależnie audytowana; Firefox ma problemy z pobieraniem zaszyfrowanych plików (znane ograniczenie, nie nasz bug). Klucz szyfrowania trafia do `config.json` w `/app/config` — **to jest część, którą trzeba backupować**, inaczej utrata configu = utrata dostępu do już zaszyfrowanych plików. ## Sieć — bind tylko na Tailscale, nigdy 0.0.0.0 Port 53842 binduje się **wyłącznie** na Tailscale IP VPS-a (`TAILSCALE_BIND_IP=100.95.58.48`), nigdy na `0.0.0.0`. Publiczny adres Hetznera (`135.181.153.108`) w ogóle nie widzi tego portu — jedyna droga na zewnątrz to `npm@VPS` (TLS na 443) → `share.okit.pl`. npm i gokapi żyją na tym samym hoście jako osobne stacki compose; npm dociera do gokapi przez Docker hairpin NAT po tym samym realnym interfejsie (ten sam trik co `fleet-prometheus`/`nextcloud` — `127.0.0.1` by tu NIE zadziałało). `GOKAPI_TRUSTED_PROXIES=172.16.0.0/12` mówi Gokapi, żeby ufał `X-Forwarded-For` z tego zakresu (podsieć mostka Docker), bo źródłowy IP po hairpinie to brama bridge'a, nie prawdziwy klient.