Files
butcem/docs/MONGODB-KURULUM.md

6.4 KiB
Raw Permalink Blame History

MongoDB kurulumu (canlı, Dokploy)

BÜTÇEM çok adımlı yazmaları (transfer, "Alışverişi tamamla", kart ödemesi…) MongoDB transaction ile yapar. Transaction yalnızca replica set üzerinde çalışır; tek sunucu için tek düğümlü replica set (rs0) yeterlidir. Uygulama başlarken bunu kontrol eder; replica set yoksa açık bir hata mesajıyla durur.

Bu belge mevcut kurulumu esas alır: Dokploy'da mongo:7 veritabanı servisi (mongo:8 sunucu çekirdeğiyle uyumsuz), kimlik doğrulama açık, butcem_root (yönetici) ve butcem_app (uygulama) kullanıcıları oluşturulmuş. Uygulama mongo:7.0 ile test edilmiştir (tüm entegrasyon testleri).

Komutlar Atlas sunucusunda çalıştırılır. <…> ile gösterilen yerleri kendi değerlerinizle değiştirin. Parolaları komut geçmişine yazmamak için mongosh parola sorduğunda girin.


1. MongoDB konteynerini bul

docker ps --format '{{.Names}}' | grep -i mongo

Çalışan konteynerlerin adlarından MongoDB'ninkini listeler. Dokploy ada rastgele bir son ek ekler (ör. butcem-mongo-a1b2c3.1.xyz). Aşağıda bu adı <MONGO> olarak kullanın; adın ayırt edici başlangıcı (ör. butcem-mongo-a1b2c3) da yeterlidir.

MONGO=$(docker ps -q --filter name=<mongo-servis-adı> | head -n1); echo "$MONGO"

Konteyner kimliğini bir değişkene alır; sonraki komutlar $MONGO ile kısalır.

2. Replica set açık mı?

docker exec -it "$MONGO" mongosh -u butcem_root --authenticationDatabase admin \
  --eval 'try { const s = rs.status(); print(s.set, s.members[0].stateStr) } catch (e) { print("REPLICA SET YOK: " + e.codeName) }'

Yönetici olarak bağlanıp replica set durumunu yazdırır (parolayı sorar).

  • Çıktı rs0 PRIMARY ise replica set hazır; 4. adıma geçin.
  • Çıktı REPLICA SET YOK: NoReplicationEnabled ise 3. adımı uygulayın.

3. Tek düğümlü replica set'i aç

Dokploy'un MongoDB servisinde bir "Replica Set" seçeneği varsa (sürüme göre değişir) onu açıp servisi yeniden deploy etmeniz ve 3.4'e geçmeniz yeterlidir. Yoksa aşağıdaki elle yöntemi uygulayın. Kimlik doğrulama açıkken replica set bir anahtar dosyası (keyfile) ister.

3.1 Yedek alın

docker exec -it "$MONGO" mongodump -u butcem_root --authenticationDatabase admin --gzip --archive=/data/db/oncesi.archive.gz
docker cp "$MONGO":/data/db/oncesi.archive.gz ~/mongo-oncesi.archive.gz && docker exec "$MONGO" rm /data/db/oncesi.archive.gz

Değişiklikten önce tüm veritabanlarının yedeğini konteyner içinde bir dosyaya alır (parolayı sorar), sonra ev dizinine kopyalayıp konteynerdeki kopyayı siler. Yeni kurulumda veri yoksa atlanabilir.

3.2 Anahtar dosyasını oluştur

docker exec "$MONGO" sh -c 'head -c 756 /dev/urandom | base64 > /data/db/rs-keyfile && chmod 400 /data/db/rs-keyfile && chown 999:999 /data/db/rs-keyfile && ls -l /data/db/rs-keyfile'

Kalıcı veri volume'u (/data/db) içinde rastgele bir anahtar dosyası üretir; yalnızca mongodb kullanıcısı (uid 999) okuyabilir. Çıktıda -r-------- … mongodb mongodb görmelisiniz. Dosya volume'da olduğu için yeniden başlatmalarda korunur.

3.3 Başlatma komutunu değiştir ve yeniden deploy et

Dokploy › MongoDB servisi › Advanced sekmesi › Command alanına:

mongod --replSet rs0 --bind_ip_all --keyFile /data/db/rs-keyfile

yazıp kaydedin ve servisi Redeploy edin. (MONGO_INITDB_ROOT_* ortam değişkenleri yerinde kaldığı için kimlik doğrulama açık kalır.) Konteyner yeniden oluşacağından 1. adımdaki MONGO değişkenini yeniden alın.

3.4 Replica set'i başlat (tek seferlik)

docker exec -it "$MONGO" mongosh -u butcem_root --authenticationDatabase admin \
  --eval 'rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })'

rs0 adlı tek üyeli replica set'i başlatır; çıktıda { ok: 1 } görmelisiniz. Uygulama directConnection=true ile bağlandığı için üye adresinin localhost olması sorun değildir.

Birkaç saniye sonra 2. adımdaki kontrolü tekrarlayın: rs0 PRIMARY.

4. Uygulama kullanıcısını doğrula

docker exec -it "$MONGO" mongosh -u butcem_root --authenticationDatabase admin --eval '
  for (const d of ["admin", "butcem"]) {
    const u = db.getSiblingDB(d).getUser("butcem_app");
    if (u) print("tanımlı veritabanı:", d, "| roller:", JSON.stringify(u.roles));
  }'

butcem_app kullanıcısının hangi veritabanında tanımlı olduğunu (bağlantı dizesindeki authSource) ve rollerini yazdırır. Beklenen rol: [{"role":"readWrite","db":"butcem"}].

Rol farklıysa düzeltin:

docker exec -it "$MONGO" mongosh -u butcem_root --authenticationDatabase admin \
  --eval 'db.getSiblingDB("<authSource>").updateUser("butcem_app", { roles: [{ role: "readWrite", db: "butcem" }] })'

Uygulama kullanıcısına yalnızca butcem veritabanında okuma-yazma yetkisi verir (migration'lar index oluşturmak için bu yetkiyle yetinir).

5. Bağlantı dizesi (Dokploy uygulama ortam değişkeni)

MONGODB_URI=mongodb://butcem_app:<parola-url-kodlu>@<iç-host>:27017/butcem?authSource=<authSource>&replicaSet=rs0&directConnection=true
  • <iç-host>: Dokploy › MongoDB servisi › Internal Host (ör. butcem-mongo-a1b2c3). Uygulama ve veritabanı aynı Dokploy ağında olduğundan dışa port açmaya gerek yoktur; açmayın.
  • <authSource>: 4. adımın çıktısındaki veritabanı (admin veya butcem).
  • Parolada @ : / ? # % gibi karakterler varsa URL kodlayın:
    python3 -c 'import urllib.parse,getpass; print(urllib.parse.quote(getpass.getpass(), safe=""))'
    
    Parolayı sorar ve bağlantı dizesine yazılacak kodlu hâlini basar (geçmişe düşmez).

6. Transaction denemesi (isteğe bağlı)

docker exec -it "$MONGO" mongosh "mongodb://butcem_app@localhost:27017/butcem?authSource=<authSource>&replicaSet=rs0&directConnection=true" --eval '
  const s = db.getMongo().startSession(); const c = s.getDatabase("butcem").getCollection("tx_probe");
  s.startTransaction(); c.insertOne({ a: 1 }); s.commitTransaction();
  print("transaction tamam:", db.getSiblingDB("butcem").getCollection("tx_probe").countDocuments({}));
  db.getSiblingDB("butcem").getCollection("tx_probe").drop();'

Uygulama kullanıcısıyla bağlanıp küçük bir transaction yazar, sonucu basar ve deneme koleksiyonunu siler. transaction tamam: 1 görmelisiniz.