Aplikasi jarang berjalan dalam satu salinan: ada salinan pengembangan di laptop, salinan staging untuk pengujian menyeluruh, dan salinan produksi yang melayani pengguna nyata. Di cloud, memisahkan ketiganya bukan sekadar membuat tiga database berbeda — melainkan tiga wadah yang benar-benar terpisah. Chapter ini menjelaskan mengapa pemisahan per project adalah pola yang tepat, bagaimana menamaininya agar konsisten, dan bagaimana data berpindah antar environment dengan aman.
Bahaya Dua Environment dalam Satu Cluster #
Cara pemisahan yang paling mudah terlinting adalah membuat database tokobuku_dev dan tokobuku_prod dalam satu cluster. Kita simulasikan bentuknya pada server latihan:
use latihan_campurOutput yang Dihasilkan:
switched to db latihan_campurdb.getSiblingDB("latihan_campur_dev").produk.insertMany([
{ nama: "Buku Atlas", harga: 95000 },
{ nama: "Buku Kompas", harga: 75000 }
])
db.getSiblingDB("latihan_campur_prod").produk.insertMany([
{ nama: "Pesanan Budi", total: 170000 },
{ nama: "Pesanan Siti", total: 95000 },
{ nama: "Pesanan Dewi", total: 75000 }
])Output yang Dihasilkan:
{
acknowledged: true,
insertedIds: {
'0': ObjectId('6ad3fbc9167252209eba55d2'),
'1': ObjectId('6ad3fbc9167252209eba55d3')
}
}
{
acknowledged: true,
insertedIds: {
'0': ObjectId('6ad3fbc9167252209eba55d4'),
'1': ObjectId('6ad3fbc9167252209eba55d5'),
'2': ObjectId('6ad3fbc9167252209eba55d6')
}
}Dari satu koneksi yang sama, kedua “environment” bisa kita akses dan audit sekaligus:
const audit = db.adminCommand({ listDatabases: 1, filter: { name: /^latihan_campur/ } })
printjson(audit.databases.map(d => ({ nama: d.name, ukuranKB: Math.round(d.sizeOnDisk / 1024) })))Output yang Dihasilkan:
[
{
nama: 'latihan_campur_dev',
ukuranKB: 8
},
{
nama: 'latihan_campur_prod',
ukuranKB: 8
}
]Di sinilah masalahnya: satu koneksi menguasai keduanya. Satu kesalahan dropDatabase, satu kredensial aplikasi yang bocor, atau satu kehabisan batas koneksi cluster berdampak ke environment dev sekaligus prod. Luas dampak seperti ini disebut blast radius — dan pemisahan bertujuan mengecilkannya. Buktinya mudah: dari koneksi yang sama, keduanya bisa dihapus dalam dua baris:
db.getSiblingDB("latihan_campur_dev").dropDatabase()
db.getSiblingDB("latihan_campur_prod").dropDatabase()Output yang Dihasilkan:
{ ok: 1, dropped: 'latihan_campur_dev' }
{ ok: 1, dropped: 'latihan_campur_prod' }Satu Project per Environment #
Pada Atlas, wadah pemisah yang tepat adalah Project, bukan database. Alasannya sudah kita kenal dari dua Chapter sebelumnya: database user dan IP access list berlaku untuk seluruh cluster dalam satu project. Cluster dev dan prod dalam satu project dengan sendirinya berbagi kredensial aplikasi — membatalkan tujuan pemisahan.
Diagram di atas memperlihatkan tiga project di bawah satu organization: tiap project memiliki cluster, database user, dan aturan jaringan sendiri. Sebuah kejadian di dev — cluster terhapus, user bocor, tagihan melonjak — tidak pernah menyentuh produksi.
Konvensi Penamaan #
Nama yang konsisten membuat siapa pun langsung tahu sedang bekerja pada environment mana. Pola <produk>-<environment> pada nama project dan cluster sudah cukup:
| Project | Tier cluster | Isi data | Pemakai |
|---|---|---|---|
tokobuku-dev | M0 atau Flex | Data sintetis | Seluruh tim pengembang |
tokobuku-staging | Flex atau M10 | Salinan anonim dari prod | Tim pengembang + QA |
tokobuku-prod | Dedicated M10+ | Data nyata | Hanya aplikasi + on-call |
Nama database user tetap sama antar environment (app-tokobuku), sehingga kode aplikasi hanya perlu mengganti nilai MONGODB_URI per environment — nama user, nama database, dan nama collection identik.
Data Sintetis dan Data Nyata #
Environment berbeda layak diisi data berbeda. Dev cukup memakai data sintetis: hasil generator atau seed script kecil yang kita tulis sendiri, karena kebutuhannya hanya menjalankan kode. Staging membutuhkan volume dan sebaran mendekati nyata sehingga migrasi dan indeks teruji bermakna — gunakan salinan dari produksi yang sudah dianonimkan. Produksi menyimpan data nyata.
Promosi Antar Environment #
Dua hal berpindah antar environment dengan arah berbeda. Kode, skema, dan index mengalir satu arah dari dev ke staging lalu produksi, lewat migration script yang sama yang kita jalankan di Chapter Deployment Checklist. Data mengalir sebaliknya — dari produksi ke staging — melalui backup yang di-restore:
# ambil snapshot data staging untuk pengujian di mesin lokal
mongodump --uri "mongodb+srv://[email protected]/tokobuku" \
--gzip --archive=staging.gz
# pulihkan ke database uji di server lokal dengan nama berbeda
mongorestore --uri "mongodb://127.0.0.1:27017/?directConnection=true" \
--gzip --archive=staging.gz --nsFrom="tokobuku.*" --nsTo="tokobuku_uji.*"Opsi --archive memadat seluruh database ke satu berkas, sedangkan --nsFrom/--nsTo mengubah nama namespace saat pemulihan agar tidak menimpa data yang ada. Pada cluster Dedicated, snapshot backup Atlas juga dapat dipulihkan ke cluster lain di project yang berbeda — pola yang lazim untuk membangun staging baru.
Rangkuman #
- Memisahkan environment lewat database dalam satu cluster membuat satu koneksi menguasai semuanya — blast radius terlalu besar.
- Wadah pemisah yang benar adalah Project: database user dan IP access list berlaku per project, sehingga dev dan prod terpisah total.
- Konvensi
tokobuku-dev/tokobuku-staging/tokobuku-proddengan nama user yang sama membuat aplikasi cukup menggantiMONGODB_URI. - Dev memakai data sintetis, staging memakai salinan anonim, produksi menyimpan data nyata; jangan pernah membawa data mentah keluar dari project produksi.
- Kode mengalir dev → staging → prod lewat migration script; data mengalir prod → staging lewat
mongodump/mongorestoreatau restore snapshot Atlas.