- 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
139 lines
3.6 KiB
Markdown
139 lines
3.6 KiB
Markdown
# Runbook 10 — nowa usługa
|
|
|
|
Od pustego katalogu do działającej aplikacji na własnej subdomenie z HTTPS.
|
|
|
|
---
|
|
|
|
## 1. Ustalenia przed startem
|
|
|
|
| Pytanie | Po co |
|
|
|---|---|
|
|
| Nazwa projektu (małe litery, myślnik) | katalog, kontenery, sieć, subdomena |
|
|
| Publiczna czy wewnętrzna? | czy w ogóle wchodzi do sieci `edge` |
|
|
| Baza danych? Jaka? | osobny kontener w sieci wewnętrznej + wpis do backupu |
|
|
| Dane trwałe? Gdzie? | bind-mount w `/srv/data/<projekt>` |
|
|
| Wysyłka maili? | zewnętrzny SMTP, nigdy lokalny |
|
|
| Szacowane zużycie dysku | 100 GB to nasz limit |
|
|
|
|
---
|
|
|
|
## 2. Struktura
|
|
|
|
```bash
|
|
mkdir -p /srv/apps/<projekt>
|
|
mkdir -p /srv/data/<projekt>
|
|
cd /srv/apps/<projekt>
|
|
git init
|
|
```
|
|
|
|
Minimum plików: `compose.yaml`, `.env.example`, `.gitignore` (z `.env`), `README.md`.
|
|
|
|
---
|
|
|
|
## 3. Wzorzec compose
|
|
|
|
```yaml
|
|
services:
|
|
web:
|
|
image: <obraz>:<KONKRETNA-WERSJA> # nigdy :latest
|
|
container_name: <projekt>-web
|
|
restart: unless-stopped
|
|
env_file: .env
|
|
networks:
|
|
- edge
|
|
- internal
|
|
volumes:
|
|
- /srv/data/<projekt>/web:/app/data
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.<projekt>.rule=Host(`<projekt>.dfkk.cloud`)"
|
|
- "traefik.http.routers.<projekt>.entrypoints=websecure"
|
|
- "traefik.http.routers.<projekt>.tls.certresolver=ovh"
|
|
- "traefik.http.services.<projekt>.loadbalancer.server.port=<PORT-WEWNĘTRZNY>"
|
|
|
|
db:
|
|
image: postgres:16.4
|
|
container_name: <projekt>-db
|
|
restart: unless-stopped
|
|
env_file: .env
|
|
networks:
|
|
- internal # BEZ edge — baza nie widzi świata
|
|
volumes:
|
|
- /srv/data/<projekt>/db:/var/lib/postgresql/data
|
|
|
|
networks:
|
|
edge:
|
|
external: true
|
|
internal:
|
|
name: <projekt>-internal
|
|
```
|
|
|
|
**Trzy rzeczy, na które patrzysz w tym pliku:**
|
|
|
|
1. Brak sekcji `ports:` — ruch wchodzi wyłącznie przez Traefika.
|
|
Opublikowany port omija ufw i jest widoczny z internetu.
|
|
2. `db` jest tylko w `internal`. Kontener w sieci `edge` jest osiągalny
|
|
dla każdej innej usługi w `edge` — baza nie ma tam czego szukać.
|
|
3. Wersja obrazu przypięta. `:latest` oznacza, że przyszły `pull` może
|
|
podmienić działającą aplikację na wersję z breaking changes.
|
|
|
|
---
|
|
|
|
## 4. Sekrety
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
chmod 600 .env
|
|
openssl rand -base64 32 # tak generujemy hasła, nie wymyślamy ich
|
|
```
|
|
|
|
Sprawdź, że `.env` jest w `.gitignore`, **zanim** zrobisz pierwszy commit.
|
|
Sekret raz wypchnięty do repo trzeba unieważnić, nie usunąć.
|
|
|
|
---
|
|
|
|
## 5. DNS
|
|
|
|
Rekord A dla `<projekt>.dfkk.cloud` na IP serwera — panel OVH.
|
|
Certyfikat leci z wildcardu `*.dfkk.cloud`, więc **nic dodatkowo nie robisz**.
|
|
Szczegóły: `20-domena.md`.
|
|
|
|
---
|
|
|
|
## 6. Uruchomienie
|
|
|
|
```bash
|
|
docker compose config # walidacja składni i podstawionych zmiennych
|
|
docker compose up -d
|
|
docker compose ps
|
|
docker compose logs -f --tail=50
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Weryfikacja — sprawdzasz, nie zakładasz
|
|
|
|
```bash
|
|
curl -I https://<projekt>.dfkk.cloud # 200 lub 3xx, certyfikat ważny
|
|
docker compose ps # wszystko "Up", nic w restart loop
|
|
docker stats --no-stream # zużycie w granicach rozsądku
|
|
```
|
|
|
|
Test negatywny — potwierdzenie, że baza **nie** jest wystawiona:
|
|
|
|
```bash
|
|
# z lokalnej maszyny, nie z serwera:
|
|
nc -zv <IP-serwera> 5432 # ma odmówić połączenia
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Domknięcie
|
|
|
|
- [ ] Commit w repo projektu, push do Gitei
|
|
- [ ] Wpis w `SERVER.md`: projekt, katalog, repo, domena, wolumeny, baza
|
|
- [ ] Wpis w `SERVER.md`, sekcja 2: zajęta subdomena
|
|
- [ ] Jeśli są dane trwałe — dopisanie ścieżki do listy backupu
|
|
- [ ] Monitor w Uptime Kuma
|
|
- [ ] `df -h` — kontrola, ile dysku ubyło
|