# 🚀 Canlıya Alma (Atlas Homeserver + Dokploy) > Durum: ✅ Yayında — https://kakeibo.ta1sph.website (2026-11-12) · Yedekleme: betikler hazır, sunucuda kurulum bekliyor (§6) ## 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>@: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.` | `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 - Dokploy'da **ayrı** MongoDB servisi (Bütçem'in veritabanı paylaşılmaz): proje `Kakeibo` → Database → MongoDB `kakeibo-mongo`. - Servis (iç ağ) adı: **`kakeibo-kakeibomongo-fibzhc`**, imaj `mongo:7`, ağ `dokploy-network`, volume `kakeibo-kakeibomongo-fibzhc-data → /data/db`. - Replica set: `rs0`, üye `kakeibo-kakeibomongo-fibzhc:27017` (Dokploy "Replica Sets" açık). - Kullanıcılar: `kakeibo_root` (admin, `root`) · `kakeibo_app` (`kakeibo` DB, yalnızca `readWrite`). Şifreler 2026-11-12'de yenilendi (eskileri açığa çıkmıştı). - Dış erişim: `docker service inspect … .Endpoint.Ports` → `null` (port yayınlanmıyor) ✅. External Port alanı boş kalmalı. - Bağlantı: ``` mongodb://kakeibo_app:@kakeibo-kakeibomongo-fibzhc:27017/kakeibo?authSource=kakeibo&replicaSet=rs0 ``` ### ⚠️ Açık konu: MongoDB kimlik doğrulaması kapalı Dokploy'un replica set betiği `mongod --replSet rs0 --bind_ip_all` ile başlatıyor (`--keyFile` yok) ve her deploy'da Advanced → Command/Args'ı yok sayıp kendi betiğini yazıyor. Sonuç: kullanıcılar tanımlı ama şifre **zorunlu değil**; `dokploy-network`'teki herhangi bir konteyner erişebilir. İnternetten erişim yok. Çözüm adayları (ileride): Dokploy'un MongoDB'si yerine Compose servisi (kendi komutumuzla `--keyFile`) ya da Dokploy'da keyFile desteği. Uygulama zaten kullanıcı/şifreyle bağlandığı için auth açıldığında uygulamada değişiklik gerekmez. ### Şifre girerken dikkat - `mongosh` içinde `passwordPrompt()`'a **yapıştırmayın** (terminal görünmez karakter ekleyebiliyor → `U_STRINGPREP_PROHIBITED_ERROR`). Bunun yerine: `const p = require('crypto').randomBytes(24).toString('hex'); db.changeUserPassword("kakeibo_app", p); print(p)` - Şifreyi komuta düz yazmayın; sonra `rm -f /root/.mongodb/mongosh/mongosh_repl_history`. - "Rebuild Database" veriyi siler ve Dokploy betiği yeni root şifresini servis ayarına düz metin yazar. ## 5. Dokploy kurulumu Proje `Kakeibo` → Create Service → **Application** `kakeibo-app` (iç ad: `kakeibo-kakeiboapp-nd5kek`). | Bölüm | Ayar | |---|---| | General → Provider | **Gitea** sekmesi (varsayılan GitHub sekmesi seçili kalırsa: `Github Provider not found`) → repo `suphicakir/kakeibo`, branch `main`, Build Path `/` → **Save** | | General → Build Type | **Dockerfile**, dosya `Dockerfile`, context `.` | | Environment | §2'deki değişkenler (`MONGODB_URI`, `JWT_SECRET`, `APP_URL=https://kakeibo.ta1sph.website`, `REGISTRATION=invite_only`, `RUST_LOG`) | | Domains | Host `kakeibo.ta1sph.website`, Path `/`, **Container Port `8080`**, HTTPS açık, Let's Encrypt | | Auto Deploy | Açık → Gitea'ya push = otomatik yayın | Notlar: - İlk derleme ~6–10 dk (Rust bağımlılıkları); sonrakiler katman önbelleğiyle daha hızlı. - Derleme hatası **Deployments** → ilgili deploy logunda görünür; **Logs** sekmesi yalnızca çalışan konteyneri gösterir. - Dokploy, Gitea'daki son commit'i derler → değişiklikler önce push edilmeli. - Geri dönüş (rollback): Deployments listesinden önceki başarılı deploy seçilerek yeniden yayınlanır. - DNS: `kakeibo.ta1sph.website` → ev dış IP'si; modemde 80/443 → Atlas yönlendirmesi Let's Encrypt için gerekli. - Sade metin `404 page not found` + "Not secure" = Traefik'in kendi yanıtı (bu host için router yok): domain eklenip **Redeploy** yapılmamış ya da konteyner çalışmıyor demektir. ### İlk yayın kontrolü (2026-11-12) ✅ - `/api/health` → `{"status":"ok","db":"ok"}`, servis `1/1` healthy, migration v1 + indeksler canlı DB'de oluştu. - TLS: Let's Encrypt (otomatik yenileme), `/kayit` doğrudan açılıyor (SPA). - İlk hesap açıldı → `GET /api/auth/registration` = `new_household_allowed: false` (yalnızca davet). ## 6. Yedekleme ve geri yükleme ``` Atlas 03:30 backup.sh ──▶ /var/backups/kakeibo/kakeibo-YYYY-MM-DD_HHMM.archive.gz (son 14) │ rsync (SSH) Bu bilgisayar 09:00 / açılışta ──▶ ~/Yedekler/kakeibo/ (son 60, 2 günden eskiyse masaüstü uyarısı) ``` | Dosya | Nerede çalışır | İş | |---|---|---| | `scripts/backup.sh` | Atlas → `/usr/local/lib/kakeibo/` | `mongodump --archive --gzip` → gzip + `mongorestore --dryRun` denetimi → son 14'ü tutar | | `scripts/restore.sh` | Atlas (ve yerelde `npm run db:restore`) | yedeği **başka adla** geri yükler, kayıt sayılarını gösterir/karşılaştırır | | `scripts/backup-pull.sh` | bu bilgisayar | yeni yedekleri çeker, eskiyse uyarır | | `deploy/systemd/*` | ikisi | zamanlayıcılar (`Persistent=true`: kapalıyken kaçan çalışma açılınca yapılır) | Yerel deneme: `npm run db:backup` (kakeibo_dev → `./backups`, git'e girmez) · `COMPARE_DB=kakeibo_dev npm run db:restore -- latest kakeibo_restore_test`. ### 6.1 Atlas'ta kurulum (bir kez) Bu bilgisayarda, proje klasöründe: ```bash scp scripts/backup.sh scripts/restore.sh deploy/systemd/kakeibo-backup.service deploy/systemd/kakeibo-backup.timer atlas:/tmp/ ssh atlas ``` Atlas'ta: ```bash sudo install -Dm755 /tmp/backup.sh /usr/local/lib/kakeibo/backup.sh sudo install -Dm755 /tmp/restore.sh /usr/local/lib/kakeibo/restore.sh sudo install -m644 /tmp/kakeibo-backup.service /tmp/kakeibo-backup.timer /etc/systemd/system/ ``` - SSH'ye **root olmayan** bir kullanıcıyla bağlanıyorsanız: `sudo systemctl edit --full kakeibo-backup.service` → `#Environment=BACKUP_GROUP=…` satırının başındaki `#`'i kaldırıp kendi kullanıcı grubunuzu yazın (yoksa yedekleri çekemezsiniz). İlk yedek ve kontrol: ```bash sudo systemctl daemon-reload sudo systemctl start kakeibo-backup.service journalctl -u kakeibo-backup -n 20 --no-pager # "tamam: …" görülmeli ``` ### 6.2 Geri yükleme denemesi (kurulumda bir kez, sonra ayda bir önerilir) Canlı veriye dokunmaz; ayrı `kakeibo_restore_test` veritabanına yükler ve sayıları karşılaştırır: ```bash sudo COMPARE_DB=kakeibo /usr/local/lib/kakeibo/restore.sh latest kakeibo_restore_test # "✅ kakeibo ile aynı" görülmeli. Sonra deneme veritabanını silin: sudo docker exec $(sudo docker ps -q -f name=kakeibo-kakeibomongo-fibzhc) mongosh --quiet kakeibo_restore_test --eval 'db.dropDatabase()' ``` Sonra zamanlayıcıyı açın: ```bash sudo systemctl enable --now kakeibo-backup.timer systemctl list-timers kakeibo-backup.timer # bir sonraki çalışma saati ``` ### 6.3 Bu bilgisayarda (sunucu dışı kopya) Önce şifresiz SSH çalışmalı: `ssh -o BatchMode=yes atlas ls /var/backups/kakeibo` yedek dosyasını listelemeli. ```bash scripts/backup-pull.sh # elle bir kez: ~/Yedekler/kakeibo/ mkdir -p ~/.config/systemd/user cp deploy/systemd/kakeibo-backup-pull.service deploy/systemd/kakeibo-backup-pull.timer ~/.config/systemd/user/ systemctl --user daemon-reload systemctl --user enable --now kakeibo-backup-pull.timer ``` - SSH'de sunucunun adı `atlas` değilse: `systemctl --user edit --full kakeibo-backup-pull.service` → `KAKEIBO_BACKUP_HOST` satırı. - Günlük: `journalctl --user -u kakeibo-backup-pull -n 20`. ### 6.4 Felaket sonrası geri yükleme (canlı veritabanının yerine) 1. Dokploy → `kakeibo-app` → **Stop** (yükleme sırasında yazma olmasın). 2. Gerekirse yedeği sunucuya kopyalayın: `scp ~/Yedekler/kakeibo/ atlas:/tmp/`. 3. Atlas'ta: `sudo /usr/local/lib/kakeibo/restore.sh /tmp/ kakeibo --force` (önce mevcut `kakeibo` silinir). 4. `kakeibo-app` → **Start**, `/api/health` ve giriş kontrolü. - MongoDB servisi tamamen yeniden kurulduysa önce §4'teki kullanıcıları (`kakeibo_app`) yeniden oluşturun. - Yedekte kullanıcı şifre özetleri (argon2) ve oturum bilgisi bulunur → yedek dosyalarını paylaşmayın. ### Notlar - MongoDB'de kimlik doğrulaması zorunlu olmadığından (§4) `mongodump` konteynerin içinden şifresiz çalışır. Auth açıldığında yedek için ayrı bir `backup` rolü kullanıcısı ve betiğe `--config` ile şifre dosyası eklenmeli. - Yedek boyutu şu an birkaç KB–MB; 14 + 60 dosya önemsiz yer tutar.