# 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 ```bash 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ı `` olarak kullanın; adın ayırt edici başlangıcı (ör. `butcem-mongo-a1b2c3`) da yeterlidir. ```bash MONGO=$(docker ps -q --filter name= | 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ı? ```bash 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 ```bash 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 ```bash 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) ```bash 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 ```bash 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: ```bash docker exec -it "$MONGO" mongosh -u butcem_root --authenticationDatabase admin \ --eval 'db.getSiblingDB("").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:@:27017/butcem?authSource=&replicaSet=rs0&directConnection=true ``` - ``: 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. - ``: 4. adımın çıktısındaki veritabanı (`admin` veya `butcem`). - Parolada `@ : / ? # %` gibi karakterler varsa URL kodlayın: ```bash 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ı) ```bash docker exec -it "$MONGO" mongosh "mongodb://butcem_app@localhost:27017/butcem?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.