- TCMB (döviz alış kuru) ve xaus.com (altın) saatlik arka planda çekilir, gün başına saklanır - Kaynak erişilemezse son kur geçerli; altın için son USD kuru kullanılır - Elle kur girişi/silme; aynı gün elle girilen kur önceliklidir - GET /portfolio: güncel değer, kâr/zarar, toplamlar, son kur çekimi - RATES_REFRESH_MINUTES ayarı Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 KiB
🚀 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ı yoksa503. - Kapanış:
SIGTERMgelince 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 |
RATES_REFRESH_MINUTES |
– | 60 |
Otomatik kur yenileme aralığı (dk); 0 → kapalı. Konteynerin internete çıkışı gerekir: www.tcmb.gov.tr (döviz), xaus.com (altın). Erişilemezse son kur kalır, elle kur girilebilir |
PORT |
– | 8080 |
İmajda ayarlı, değiştirmeyin |
STATIC_DIR |
– | /app/static |
İmajda ayarlı, değiştirmeyin |
3. Yerelde imajı deneme
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ı):
/ve/defter→index.html(Cache-Control: no-cache)/assets/*.js→ brotli/gzip,max-age=31536000, immutable/api/health→db: ok; bilinmeyen/api/...→ JSON 404- Docker
HEALTHCHECK→ healthy; süreçkakeibokullanıcısıyla çalışır 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 → MongoDBkakeibo-mongo. - Servis (iç ağ) adı:
kakeibo-kakeibomongo-fibzhc, imajmongo:7, ağdokploy-network, volumekakeibo-kakeibomongo-fibzhc-data → /data/db. - Replica set:
rs0, üyekakeibo-kakeibomongo-fibzhc:27017(Dokploy "Replica Sets" açık). - Kullanıcılar:
kakeibo_root(admin,root) ·kakeibo_app(kakeiboDB, yalnızcareadWrite). Ş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:<APP_ŞİFRESİ>@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
mongoshiçindepasswordPrompt()'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"}, servis1/1healthy, migration v1 + indeksler canlı DB'de oluştu.- TLS: Let's Encrypt (otomatik yenileme),
/kayitdoğ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:
scp scripts/backup.sh scripts/restore.sh deploy/systemd/kakeibo-backup.service deploy/systemd/kakeibo-backup.timer atlas:/tmp/
ssh atlas
Atlas'ta:
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:
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:
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:
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.
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ı
atlasdeğilse:systemctl --user edit --full kakeibo-backup-pull.service→KAKEIBO_BACKUP_HOSTsatırı. - Günlük:
journalctl --user -u kakeibo-backup-pull -n 20.
6.4 Felaket sonrası geri yükleme (canlı veritabanının yerine)
- Dokploy →
kakeibo-app→ Stop (yükleme sırasında yazma olmasın). - Gerekirse yedeği sunucuya kopyalayın:
scp ~/Yedekler/kakeibo/<dosya> atlas:/tmp/. - Atlas'ta:
sudo /usr/local/lib/kakeibo/restore.sh /tmp/<dosya> kakeibo --force(önce mevcutkakeibosilinir). kakeibo-app→ Start,/api/healthve 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)
mongodumpkonteynerin içinden şifresiz çalışır. Auth açıldığında yedek için ayrı birbackuprolü kullanıcısı ve betiğe--configile şifre dosyası eklenmeli. - Yedek boyutu şu an birkaç KB–MB; 14 + 60 dosya önemsiz yer tutar.