Sesja: dc1 — Budowa infrastruktury serwera — 2026-03-06
Kontekst
Sesja poświęcona budowie nowej infrastruktury serwerowej pod adresem server.example.com. Celem było:
- Uruchomienie VPS na Hetzner i wpięcie go do DNS
- Stworzenie agenta dc1 odpowiedzialnego za administrację serwerem
- Zainstalowanie k3s (lekki Kubernetes) jako platformy dla serwisów
- Zainstalowanie Traefik v3 jako ingress controllera + cert-manager (TLS)
- Wdrożenie tinyauth z Pocket ID SSO
- Zabezpieczenie
orwil.eiac.devprzez Cloudflare Access + Pocket ID
VPS — Hetzner
| IP | [SERVER_IP] |
| Hostname | server.example.com |
| Provider | Hetzner Cloud |
| OS | Ubuntu 24.04.4 LTS |
| CPU | 2 vCPU |
| RAM | 3.7 GB |
| Dysk | 38 GB SSD |
Klucz SSH: ~/.ssh/dc1_automancer_root (root access).
DNS: server.example.com → [SERVER_IP] (A record, proxied: false)
Agent dc1
Agent OpenClaw dedykowany administracji serwerem.
| Model | openai/gpt-4.1 przez OpenRouter |
| Context | 1M tokenów |
Skille
ssh, docker, kubernetes, nginx, tinyauth, system
Uwaga operacyjna
GPT-4.1 jako agent dc1 ma tendencję do raportowania bez wykonania — opisuje co trzeba zrobić zamiast robić. Instalacje k3s i Traefika musiał wykonać Orwil bezpośrednio przez SSH. Do poprawy: lepsze instrukcje z wymaganiem weryfikacji każdego kroku.
k3s (Kubernetes)
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -| Wersja | v1.34.5+k3s1 |
| Helm | v3.20.0 |
| Node | Ready (control-plane) |
| Namespace | services — dla naszych serwisów |
Traefik v3
helm install traefik traefik/traefik --namespace traefik --set service.type=LoadBalancer| Wersja | v3.6.9 (chart 39.0.4) |
| LoadBalancer | [SERVER_IP]:80/443 |
Uwaga: Traefik v3 zmienił schemat values —
ports.web.redirectToiports.websecure.tlsnie istnieją. Prosta instalacja bez tych flag wystarczy.
cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace --set crds.enabled=true| Wersja | v1.19.4 |
| ClusterIssuer | letsencrypt-prod (Ready: True) |
Uwaga: cert-manager v1.19 wymaga
ingressClassNamezamiast przestarzałegoclassw ClusterIssuer solverze. Stara konfiguracja powoduje “No such authorization” od ACME i backoff na godzinę.
tinyauth na k3s
Wdrożony na k3s w namespace services, z TLS przez cert-manager.
| URL | https://auth.server.example.com |
| TLS | Let’s Encrypt (Ready) |
| IDP | Pocket ID (sso.cynar.ski) |
| Middleware | tinyauth-auth w namespace services |
Pułapki instalacji
- Zła nazwa zmiennych — tinyauth v3 używa
APP_URL,SECRET,GENERIC_*(bez prefiksuTINYAUTH_). Nowe wersje (v5+) używająTINYAUTH_APPURLitp. - SECRET musi mieć dokładnie 32 znaki —
openssl rand -hex 16(nie base64). - cert-manager HTTP-01 challenge — wymaga
ingressClassNamew ClusterIssuer. Przy błędzie “No such authorization” → usuń Certificate i stwórz nowy żeby zresetować backoff.
Autoryzacja orwil.eiac.dev
Próba 1 — tinyauth forwardauth przez CF Worker ❌
CF Worker wywołuje /api/auth/traefik z cookies z requestu do orwil.eiac.dev. Problem: cookie sesji tinyauth jest ustawione dla auth.server.example.com — przeglądarka nie wysyła go do orwil.eiac.dev. Cross-domain cookie restriction → Worker zawsze widzi brak sesji → redirect na login → po zalogowaniu redirect z powrotem → login → redirect na /logout.
Próba 2 — Cloudflare Access (Zero Trust) ✅
CF Access chroni orwil.eiac.dev na poziomie Cloudflare, przed dotarciem requestu do Workera. Cookie zarządza CF w domenie cloudflareaccess.com — problem cross-domain znika.
Konfiguracja CF Access
| IDP | OIDC → Pocket ID (sso.cynar.ski) |
| App | Self-hosted → orwil.eiac.dev |
| Session | 24h |
| Auto-redirect | true (od razu na Pocket ID) |
Kluczowe endpointy:
auth_url: https://sso.cynar.ski/authorize
token_url: https://sso.cynar.ski/api/oidc/token
certs_url: https://sso.cynar.ski/.well-known/jwks.json ← NIE /api/oidc/jwks (pusty!)
Callback URL w Pocket ID:
https://cynarski.cloudflareaccess.com/cdn-cgi/access/callback
Scopes: ["openid", "email", "profile", "groups"]
groupsbył kluczowy — bez niego Pocket ID nie zwracał emaila w ID tokenie i CF Access rzucał “Failed to fetch user/group information”.
Stan końcowy
| Serwis | URL | Status |
|---|---|---|
| dc1 k3s | server.example.com | ✅ Running |
| tinyauth | https://auth.server.example.com | ✅ Running + TLS |
| orwil site | https://orwil.eiac.dev | ✅ Chroniony przez CF Access + Pocket ID |
Flow:
przeglądarka → orwil.eiac.dev
→ CF Access (brak sesji?) → Pocket ID SSO (sso.cynar.ski)
→ po zalogowaniu → orwil.eiac.dev (CF Worker → R2)
Do zrobienia
- Posprzątać tinyauth — pozostaje na k3s jako middleware dla innych serwisów na dc1
- Zaktualizować SERVER.md agenta dc1 o finalny stan
- Rozważyć ulepszenie promptów dc1 żeby faktycznie wykonywał zadania zamiast je opisywać
