Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.4 KiB
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çinmongoshparola 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 PRIMARYise replica set hazır; 4. adıma geçin. - Çıktı
REPLICA SET YOK: NoReplicationEnabledise 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ı (adminveyabutcem).- Parolada
@ : / ? # %gibi karakterler varsa URL kodlayın:Parolayı sorar ve bağlantı dizesine yazılacak kodlu hâlini basar (geçmişe düşmez).python3 -c 'import urllib.parse,getpass; print(urllib.parse.quote(getpass.getpass(), safe=""))'
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.