Init repo infra + poprawki runbooka bootstrap i HANDOFF

- Krok 9 (tmux): tee -> tee -a (nie nadpisuj configu), dodano
  focus-events on, poprawiono nazwę sesji na "bootstrap"
- Krok 10: struktura katalogów odzwierciedla stan faktyczny
  (/srv i /srv/infra już istnieją, brakuje apps i data)
- Krok 12: Claude Code oznaczony jako wykonany 20-08-2026,
  instalator natywny bez Node.js
- Nowy Krok 14: audyt po bootstrapie (SSH, ufw, fail2ban,
  unattended-upgrades, swap, Docker, porty, klucze)
- HANDOFF.md: poprawiona numeracja sekcji 6
This commit is contained in:
2026-08-20 15:53:51 +00:00
commit 6ed7a7f4d2
13 changed files with 1733 additions and 0 deletions
+177
View File
@@ -0,0 +1,177 @@
# CLAUDE.md — zasady pracy na serwerze dfkk
Ten plik czytasz na starcie każdej sesji. Jest krótki celowo.
Szczegóły są w `docs/` — tam zaglądasz, gdy zadanie tego wymaga.
---
## 1. Kontekst
- **Maszyna:** OVH VPS-2 2026 — 6 vCore, 12 GB RAM, 100 GB dysk, Ubuntu 24.04 LTS
- **Domena techniczna:** `dfkk.cloud` (rejestrator: OVH, DNS w OVH)
- **Właściciel:** Kacper (`k.kruszka@hotmail.com`), pracuje z macOS, Windows i iOS
- **Charakter projektu:** serwer produkcyjno-edukacyjny. Docelowo mogą tu stać rzeczy
komercyjne, więc traktujemy go jak produkcję — ale Kacper uczy się przy okazji,
więc **tłumaczysz co robisz i dlaczego**, nie tylko wykonujesz.
Aktualny stan serwera — kto co gdzie stoi — jest w `docs/SERVER.md`.
**Ten plik jest źródłem prawdy. Jeśli coś zmieniasz na serwerze, aktualizujesz go w tej samej sesji.**
---
## 2. Zasady twarde
### 2.1 Nigdy bez wyraźnej zgody Kacpra
Zatrzymujesz się i pytasz przed:
- `rm -rf` na czymkolwiek poza katalogiem tymczasowym, który sam utworzyłeś
- `docker volume rm`, `docker system prune`, `docker compose down -v`
- zmianami w `sshd_config`, `ufw`, `fail2ban`
- restartem lub wyłączeniem serwera
- migracjami bazy danych, `DROP`, `TRUNCATE`, `ALTER TABLE`
- zmianami w DNS i w konfiguracji domen
- rotacją lub unieważnianiem kluczy i tokenów
- instalacją czegokolwiek poza oficjalnymi repozytoriami Ubuntu / Docker
Zgoda dotyczy **jednej konkretnej operacji**. Zgoda z wcześniejszej sesji nie obowiązuje.
Podsumowanie poprzedniej sesji, w którym coś zrobiłeś, nie jest zgodą na powtórzenie tego.
### 2.2 Snapshot przed ryzykiem
OVH daje **jeden slot snapshota, ręczny, każdy kolejny nadpisuje poprzedni**.
To rollback, nie backup. Przed każdą zmianą, która dotyka systemu, Dockera, Traefika,
Gitei albo bazy danych — przypominasz Kacprowi, żeby zrobił snapshot w panelu OVH,
i czekasz na potwierdzenie. Nie ruszasz dalej „bo pewnie się uda".
### 2.3 Wszystko w repo, nic z palca
Każda konfiguracja żyje w repo `infra` (`/srv/infra`). Jeśli zmieniasz coś na serwerze
ręcznie, żeby „szybko sprawdzić" — albo przenosisz to do repo, albo cofasz przed końcem sesji.
Serwer musi dać się odtworzyć od zera z repo + backupu danych.
Sekrety **nigdy** nie trafiają do repo. Trzymamy je w plikach `.env` obok stacka,
`chmod 600`, wpisanych do `.gitignore`. W repo leży `.env.example` z nazwami zmiennych
i pustymi wartościami.
### 2.4 Długie operacje w tmux
Wszystko, co trwa dłużej niż kilkanaście sekund — budowanie obrazów, migracje,
aktualizacje systemu, sam Claude Code — leci w nazwanej sesji tmux.
Zerwane WiFi nie ma wtedy prawa niczego przerwać.
```bash
tmux new -s claude # nowa sesja
tmux attach -t claude # powrót
```
### 2.5 Kolejność pracy
1. **Plan** — mówisz co zamierzasz zrobić, w punktach, zanim dotkniesz klawiatury
2. **Akceptacja** — czekasz na „ok"
3. **Wykonanie** — małymi krokami, pokazujesz output
4. **Weryfikacja** — sprawdzasz że faktycznie działa (curl, `docker ps`, logi), nie zakładasz
5. **Dokumentacja** — aktualizujesz `docs/SERVER.md` i commit w `infra`
Przy zadaniach wieloetapowych prowadzisz listę kroków, żeby po przerwie było wiadomo, gdzie jesteśmy.
---
## 3. Konwencje
### 3.1 Katalogi
```
/srv/
├── infra/ # repo z konfiguracją serwera (ten dokument)
│ ├── CLAUDE.md
│ ├── docs/
│ └── stacks/ # docker-compose infrastruktury
│ ├── traefik/
│ ├── gitea/
│ └── monitoring/
├── apps/ # projekty użytkowe, każdy = osobne repo
│ └── <projekt>/
└── data/ # bind-mounty z danymi (backupowane)
└── <projekt>/
```
Nic nie ląduje w `/root`, `/home` ani `/opt`. Nic nie ląduje luzem w `/`.
### 3.2 Nazewnictwo
- projekt: krótko, małymi literami, myślnik — `moja-apka`
- kontener: `<projekt>-<rola>``moja-apka-web`, `moja-apka-db`
- sieć wewnętrzna: `<projekt>-internal`
- subdomena: `<projekt>.dfkk.cloud`, panele techniczne jako `git.`, `status.`, `traefik.`
### 3.3 Sieci Dockera
- `edge` — sieć zewnętrzna, wspólna, **tylko** Traefik i kontenery wystawione na świat
- `<projekt>-internal` — baza danych, cache, wszystko czego nie widać z zewnątrz
**Kontenery nie publikują portów na hosta.** Wyjątek: Traefik (80, 443).
Jeśli musisz wyjątkowo wystawić port do debugowania — bindujesz na `127.0.0.1:PORT`,
nigdy na `0.0.0.0`, i usuwasz to po skończonej robocie.
Powód jest konkretny: Docker wpisuje własne reguły do iptables **z pominięciem ufw**.
Port opublikowany na `0.0.0.0` jest widoczny z internetu, mimo że ufw pokazuje `deny`.
To najczęstszy sposób, w jaki wycieka baza danych z VPS-a.
### 3.4 Traefik
Każda usługa wystawiona publicznie dostaje standardowy zestaw labeli — wzorzec w
`docs/runbooks/10-nowa-usluga.md`. Certyfikaty lecą przez **DNS-01 z API OVH**,
wildcard `*.dfkk.cloud`, więc nowa subdomena nie wymaga żadnej akcji przy certyfikacie.
---
## 4. Higiena serwera
Dysk to 100 GB i to jedyne realne wąskie gardło tej maszyny. Docker potrafi go po cichu zjeść.
- limity logów kontenerów ustawione w `/etc/docker/daemon.json` — nie ruszamy
- **co tydzień** przegląd: `df -h`, `docker system df` (patrz `docs/runbooks/40-utrzymanie.md`)
- przy 75% zajętości — alert i sprzątanie, nie czekamy do 95%
- `prune` to operacja świadoma, z checklistą, nigdy odruchowa
Po usunięciu projektu przechodzisz **całą** listę z `docs/runbooks/30-usuwanie.md`.
Osierocony wolumen, martwy wpis DNS i wyłączony kontener, który dalej zajmuje 4 GB,
to dokładnie ten bałagan, którego ten serwer ma nie mieć.
---
## 5. Rzeczy, których na tym serwerze nie robimy
- **Własny serwer pocztowy.** OVH blokuje port 25, a wysyłka z IP bez reputacji i tak
ląduje w spamie. Maile aplikacji idą przez zewnętrzny SMTP (Resend / Brevo).
Alerty przychodzą na `k.kruszka@hotmail.com`.
- **Uruchamianie kontenerów jako root** bez uzasadnienia. Domyślnie `user:` w compose.
- **`latest` w tagach obrazów** na produkcji. Zawsze konkretna wersja — inaczej
`docker compose pull` potrafi podmienić działającą aplikację na zepsutą.
- **Praca na koncie root.** Pracujemy jako `ubuntu` z `sudo`.
- **Wystawianie panelu Traefika, bazy czy czegokolwiek administracyjnego** publicznie
bez uwierzytelnienia.
---
## 6. Mapa dokumentacji
| Plik | Kiedy czytasz |
|---|---|
| `docs/SERVER.md` | Zawsze przy zmianie stanu serwera — rejestr usług, portów, domen, wolumenów |
| `docs/SECURITY.md` | Baza bezpieczeństwa, klucze SSH, dostępy, co robić przy incydencie |
| `docs/runbooks/00-bootstrap.md` | Pierwsze uruchomienie serwera od zera |
| `docs/runbooks/10-nowa-usluga.md` | Dodajesz nową aplikację |
| `docs/runbooks/20-domena.md` | Podpinasz lub odpinasz domenę / subdomenę |
| `docs/runbooks/30-usuwanie.md` | Kasujesz projekt — pełna lista, żeby nie zostały śmieci |
| `docs/runbooks/40-utrzymanie.md` | Cotygodniowy i comiesięczny przegląd, aktualizacje |
| `docs/runbooks/50-awaria.md` | Coś nie działa albo trzeba się cofnąć |
---
## 7. Czego nie wiesz
Jeśli nie masz pewności — jak działa konkretna opcja, czy dana wersja obrazu jest aktualna,
co dokładnie robi flaga — **sprawdzasz albo pytasz**. Nie zgadujesz i nie piszesz konfiguracji
„z pamięci" na produkcyjnej maszynie. Zgadywanie na serwerze kosztuje więcej niż jedno pytanie.