feat(dağıtım): Docker imajı ve Axum'un arayüzü sunması

- Çok aşamalı Dockerfile: Node (arayüz) → Rust (release) → debian-slim, root olmayan kullanıcı
- Axum, STATIC_DIR tanımlıysa derlenmiş arayüzü sunar (SPA yönlendirmesi)
- Önbellek başlıkları (HTML no-cache, /assets 1 yıl), gzip/brotli sıkıştırma, istek logları
- Bilinmeyen /api/... → JSON 404; SIGTERM'de düzgün kapanış
- HEALTHCHECK (/api/health), .dockerignore, docs/DEPLOY.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 01:26:34 +03:00
parent e188922c0f
commit ad90551c6d
14 changed files with 391 additions and 6 deletions
+56
View File
@@ -0,0 +1,56 @@
# 🚀 Canlıya Alma (Atlas Homeserver + Dokploy)
> Durum: Faz 3 — Adım 1 ✅ (Docker imajı) · Adım 2–5 devam ediyor
## 1. Mimari
```
İnternet ──HTTPS──▶ Traefik (Dokploy) ──▶ kakeibo konteyneri :8080 ──▶ MongoDB (rs0)
├─ /api/* → Rust (Axum) API
└─ diğer → derlenmiş arayüz (React)
```
- **Tek imaj, tek servis, tek alan adı** → CORS yok, cookie aynı origin'de.
- İmaj: çok aşamalı `Dockerfile` (Node → arayüz derlemesi, Rust → release derleme, `debian:trixie-slim` çalışma imajı, root olmayan kullanıcı `kakeibo`, ~175 MB).
- Sağlık kontrolü: `GET /api/health` → `200 {"status":"ok","db":"ok"}`; veritabanı yoksa `503`.
- Kapanış: `SIGTERM` gelince süren istekler bitirilir, sonra kapanır.
## 2. Ortam değişkenleri
| Değişken | Zorunlu | Örnek / varsayılan | Açıklama |
|---|---|---|---|
| `MONGODB_URI` | ✅ | `mongodb://kakeibo_app:<şifre>@<host>:27017/kakeibo?authSource=kakeibo&replicaSet=rs0` | Ayrı, yalnızca `kakeibo` DB'sinde `readWrite` yetkili kullanıcı |
| `JWT_SECRET` | ✅ | `openssl rand -hex 32` çıktısı | En az 32 karakter. **Değişirse tüm oturumlar kapanır** |
| `APP_URL` | ✅ | `https://kakeibo.<alan-adı>` | `https://` ile başlarsa cookie `Secure` olur |
| `REGISTRATION` | – | `invite_only` | `invite_only`: ilk hane serbest, sonra yalnızca davet · `open`: herkes |
| `RUST_LOG` | – | `kakeibo=info,tower_http=info` | Log seviyesi |
| `PORT` | – | `8080` | İmajda ayarlı, değiştirmeyin |
| `STATIC_DIR` | – | `/app/static` | İmajda ayarlı, değiştirmeyin |
## 3. Yerelde imajı deneme
```bash
docker build -t kakeibo .
# Yerel MongoDB (27020) ile, geliştirme sunucusuyla çakışmasın diye 8090'da:
docker run --rm --network host --env-file .env -e PORT=8090 kakeibo
# → http://localhost:8090
```
Kontrol listesi (Faz 3 – Adım 1'de doğrulandı):
- [x] `/` ve `/defter` → `index.html` (`Cache-Control: no-cache`)
- [x] `/assets/*.js` → brotli/gzip, `max-age=31536000, immutable`
- [x] `/api/health` → `db: ok`; bilinmeyen `/api/...` → JSON 404
- [x] Docker `HEALTHCHECK` → healthy; süreç `kakeibo` kullanıcısıyla çalışır
- [x] `docker stop` → düzgün kapanış logu
## 4. Canlı MongoDB
> Faz 3 – Adım 2'de birlikte doldurulacak (KAKEIBO_PROMPT §12.3).
## 5. Dokploy kurulumu
> Faz 3 – Adım 3'te birlikte doldurulacak.
## 6. Yedekleme ve geri yükleme
> Faz 3 – Adım 5'te doldurulacak (günlük `mongodump`, son 14 yedek).
+6 -1
View File
@@ -1,7 +1,7 @@
# 🧠 Proje Hafızası
## ▶️ Sıradaki Adım
**Faz 3 – Başlangıç:** Faz 3 planını sun (canlıya alma: çok aşamalı Dockerfile, Axum'un frontend'i sunması + SPA yönlendirmesi, Dokploy, canlı MongoDB kontrolü — KAKEIBO_PROMPT §12.3 sorularını kullanıcıyla birlikte, domain + HTTPS, yedekleme). Sunucuya erişim/bilgi kullanıcıdan alınacak.
**Faz 3 – Adım 2:** Kullanıcıdan bilgi bekleniyor: alan adı, Dokploy sürümü/erişimi, Gitea'nın Dokploy'a bağlı olup olmadığı, MongoDB kurulum şekli (konteyner mi, doğrudan mı; Dokploy içinde mi), replica set durumu. Sonra §12.3 komutları (kullanıcı sunucuda çalıştırır).
## 📌 Alınan Kararlar
- **Yerel demo hesapları** (`kakeibo_dev`): `demo@ornek.com` / `demo12345` (owner, "Demo Hanesi") · `es@ornek.com` / `demo12345` (member, aynı hane). `npm run db:reset` silerse API ile yeniden oluştur (ileride `db:seed`).
@@ -33,6 +33,8 @@
- Yönlendirme sonrası toast için `mutateAsync` + await kullanıldı (mutate() callback'leri bileşen kalkınca çalışmayabilir).
- **Kayıt politikası (kullanıcı kararı, 2026-11-12): Seçenek 1** → `REGISTRATION=invite_only` varsayılan; sistemde hiç hane yokken ilk kayıt yeni hane kurar (sunucu sahibi), sonra yalnızca davetle. `open` isteğe bağlı. Canlıda ilk hesabı kullanıcı `/kayit`'tan açar; demo hesaplar canlıya taşınmaz.
- Prettier ayarı eklendi (önceden yoktu → VS Code kaydedince çift tırnağa çevirebilirdi).
- Canlı imaj: node:26-alpine → rust:1.99-slim-trixie → debian:trixie-slim (ca-certificates + curl, uid 10001 `kakeibo`), 174 MB. Docker katman önbelleği için sahte lib/main ile bağımlılık derlemesi; kalıntılar `*kakeibo*` + `.fingerprint` silinir, gerçek kaynak `touch`lanır (yoksa sahte lib kullanılıyordu).
- Önbellek: HTML `no-cache`, `/assets/*` 1 yıl immutable, diğer statik 1 saat. Bilinmeyen `/api/*` → JSON 404.
- Sürümler: Rust 1.99.1 (edition 2024), Axum 0.8, React 19, Vite 8, TypeScript 7, Tailwind 4.3, shadcn 4.23, Vitest 5, react-router 8, TanStack Query 5.
## ❓ Açık Konular
@@ -68,3 +70,6 @@
### 2026-11-12 — Faz 3 öncesi
- Kullanıcı `api.http`'deki kayıt örneğini (yeni@ornek.com) hesap sandı → dosya başlığına hazır hesaplar kutusu ve "bu bir KAYIT isteğidir" uyarısı eklendi.
- Kayıt politikası: `config.rs` `RegistrationMode`, `AppError::RegistrationClosed` (403), `account::new_household_allowed`, `GET /api/auth/registration` (`RegistrationInfo` TS tipi). `tests/registration.rs` (2). Kayıt ekranı kapalıyken yalnızca davet modu + açıklama. `.env`/`.env.example`: `REGISTRATION=invite_only`. Prettier (`.prettierrc.json`, `.prettierignore`, `format` / `format:check`), tüm src biçimlendirildi (yalnızca boşluk).
### 2026-11-12 — Faz 3
- **Adım 1:** tower-http (fs, compression gzip/br, trace). `routes::app()` + `routes/spa.rs` (ServeDir + index.html fallback + cache middleware), API fallback JSON 404, `STATIC_DIR` config, graceful shutdown (SIGTERM/Ctrl+C). `Dockerfile`, `.dockerignore`, `docs/DEPLOY.md` başlatıldı. İmaj yerelde çalıştırıldı (host network, 8090): 10 kontrol + tarayıcı ekran görüntüsü geçti. İlk derlemede Docker önbellek hilesi hatası (sahte lib.rs) bulundu, düzeltildi.
+7
View File
@@ -37,3 +37,10 @@
- ✅ 3. `lib/api.ts`, TanStack Query, ts-rs tip üretimi, oturum durumu
- ✅ 4. Router (react-router), korumalı sayfalar, layout: mobil alt menü / masaüstü sol menü
- ✅ 5. Giriş / kayıt ekranları (react-hook-form + zod, beni hatırla, davet kodu), arayüz metinleri tek dosyada
## Faz 3 Adımları
- ✅ 1. Dockerfile (çok aşamalı), Axum arayüzü sunar (SPA yönlendirmesi, önbellek başlıkları, sıkıştırma), graceful shutdown, yerelde imaj testi
- ⏳ 2. Canlı MongoDB kontrolü (§12.3): kurulum şekli, replica set, ayrı kullanıcı, dış erişim
- ⏳ 3. Dokploy: Gitea bağlantısı, ortam değişkenleri, alan adı + HTTPS, ilk yayın
- ⏳ 4. Canlıda ilk hesap + kontrol listesi
- ⏳ 5. Yedekleme (mongodump, 14 gün) + geri yükleme denemesi