Blue-green deployment Bun adalah strategi rilis dengan menjalankan dua lingkungan aplikasi secara berdampingan: satu aktif menerima trafik, satu lagi dipakai untuk kandidat rilis baru. Dengan pendekatan ini, tim bisa memverifikasi versi baru lewat health check dan smoke test sebelum trafik dialihkan, lalu melakukan rollback cepat bila ada masalah.

Untuk aplikasi Bun, strategi ini cocok ketika Anda ingin meminimalkan downtime tanpa membangun pipeline yang terlalu kompleks. Kuncinya bukan hanya menyalakan instance baru, tetapi memastikan ada readiness check, liveness check, cutover yang terkontrol di reverse proxy, observability dasar setelah release, dan prosedur rollback yang jelas.

Mengapa memilih blue-green deployment untuk aplikasi Bun

Pada deploy biasa, proses restart aplikasi sering membuat koneksi terputus sesaat atau mencampur trafik ke versi yang belum siap. Blue-green deployment mengurangi risiko itu karena versi lama tetap melayani trafik sampai versi baru benar-benar lolos verifikasi.

  • Downtime lebih rendah karena cutover dilakukan setelah instance baru sehat.
  • Rollback lebih cepat karena umumnya cukup mengembalikan trafik ke lingkungan sebelumnya.
  • Verifikasi lebih aman karena versi baru bisa diuji dalam kondisi mirip produksi sebelum menerima seluruh trafik.
  • Lebih mudah diaudit karena alur rilis dan titik keputusan lebih jelas.

Trade-off-nya, Anda membutuhkan kapasitas tambahan untuk menjalankan dua lingkungan sekaligus, disiplin konfigurasi yang lebih baik, dan perhatian khusus pada migrasi database agar versi lama dan baru bisa hidup berdampingan selama masa transisi.

Arsitektur sederhana blue-green deployment Bun

Arsitektur minimal untuk tim kecil biasanya terdiri dari:

  • Reverse proxy di depan aplikasi, misalnya Nginx, HAProxy, atau load balancer serupa.
  • Dua lingkungan aplikasi: blue dan green, masing-masing menjalankan proses Bun pada port berbeda.
  • Database bersama yang harus dikelola hati-hati agar kompatibel lintas versi saat cutover.
  • Sistem log dan metrik dasar untuk memantau dampak release.
Client
  |
  v
Reverse Proxy / Load Balancer
  |-------------------------|
  v                         v
Blue (aktif)            Green (kandidat rilis)
Bun app :3001           Bun app :3002
  |                         |
  ----------- Database / Cache -----------

Dalam kondisi normal, hanya salah satu lingkungan yang menerima trafik produksi penuh. Saat rilis, lingkungan pasif di-update, diverifikasi, lalu reverse proxy dipindahkan ke lingkungan tersebut. Jika ada gangguan, trafik dikembalikan ke lingkungan sebelumnya.

Health check yang benar: readiness dan liveness

Kesalahan umum saat deploy adalah memakai satu endpoint health check untuk semua tujuan. Padahal, liveness dan readiness punya fungsi berbeda.

Liveness check

Liveness menjawab pertanyaan: apakah proses aplikasi masih hidup dan bisa merespons dasar? Endpoint ini sebaiknya ringan dan tidak bergantung pada banyak komponen eksternal. Jika proses macet, process manager atau orchestrator bisa memutuskan untuk me-restart.

Readiness check

Readiness menjawab pertanyaan: apakah instance ini siap menerima trafik nyata? Endpoint ini boleh memeriksa dependensi penting yang dibutuhkan untuk melayani request, misalnya koneksi database, inisialisasi konfigurasi, atau koneksi ke cache bila memang wajib.

Perbedaannya penting. Instance bisa saja live tetapi belum ready, misalnya aplikasi baru saja start dan masih melakukan warm-up, atau koneksi database belum tersedia.

Contoh endpoint health check di Bun

import { serve } from "bun";

let isBootstrapped = false;

async function checkDatabase() {
  // Ganti dengan pengecekan yang benar sesuai driver yang dipakai.
  // Hindari query berat; cukup query ringan atau ping koneksi.
  return true;
}

async function bootstrap() {
  // Misalnya memuat konfigurasi, koneksi pool, cache awal, dsb.
  isBootstrapped = true;
}

bootstrap();

serve({
  port: Number(process.env.PORT || 3000),
  async fetch(req) {
    const url = new URL(req.url);

    if (url.pathname === "/health/live") {
      return Response.json({ status: "ok" }, { status: 200 });
    }

    if (url.pathname === "/health/ready") {
      if (!isBootstrapped) {
        return Response.json({ status: "starting" }, { status: 503 });
      }

      const dbOk = await checkDatabase();
      if (!dbOk) {
        return Response.json({ status: "degraded", db: false }, { status: 503 });
      }

      return Response.json({ status: "ready", db: true }, { status: 200 });
    }

    if (url.pathname === "/") {
      return new Response("hello from Bun app");
    }

    return new Response("Not Found", { status: 404 });
  }
});

Prinsip praktis:

  • Liveness jangan terlalu pintar. Jika endpoint ini ikut memeriksa semua dependensi eksternal, restart bisa terjadi berulang karena gangguan sementara di luar proses aplikasi.
  • Readiness harus mencerminkan kesiapan nyata. Jika aplikasi tak bisa melayani request tanpa database, maka cek database layak dimasukkan.
  • Hindari query berat pada health check karena endpoint ini akan dipanggil sering.

Alur release blue-green deployment Bun yang aman

Berikut alur rilis yang realistis untuk tim kecil tanpa tooling yang terlalu rumit.

1. Tentukan lingkungan aktif dan pasif

Misalnya blue sedang aktif di port 3001, sedangkan green pasif di port 3002. Reverse proxy saat ini mengarah ke blue.

2. Deploy versi baru ke lingkungan pasif

Salin artefak atau source code ke lingkungan pasif, pasang dependensi yang dibutuhkan, lalu jalankan proses Bun baru di port lingkungan tersebut. Jangan ubah trafik dulu.

3. Jalankan readiness check dan smoke test

Setelah proses menyala, verifikasi endpoint /health/ready hingga statusnya siap. Lalu lakukan smoke test ke endpoint penting, misalnya:

  • endpoint API utama merespons 200
  • autentikasi dasar berjalan
  • halaman atau route kritikal bisa dimuat
  • koneksi ke database bekerja

Contoh smoke test sederhana dengan shell:

set -e

BASE_URL="http://127.0.0.1:3002"

curl -fsS "$BASE_URL/health/ready" > /dev/null
curl -fsS "$BASE_URL/" > /dev/null
curl -fsS "$BASE_URL/api/ping" > /dev/null

echo "Smoke test passed"

Jika aplikasi memerlukan autentikasi atau data uji, gunakan akun non-produksi atau token khusus yang aman. Jangan menaruh kredensial sensitif di script tanpa pengamanan.

4. Cutover trafik di reverse proxy

Setelah verifikasi lolos, ubah reverse proxy agar trafik mengarah ke lingkungan baru. Pada tahap ini, versi baru mulai menerima trafik produksi.

5. Pantau metrik dan log pasca-release

Beberapa menit pertama setelah cutover adalah fase paling penting. Jangan langsung menghapus lingkungan lama. Biarkan tetap siap untuk rollback cepat.

6. Rollback jika indikator gagal muncul

Bila error rate naik, latensi memburuk, atau fitur kritikal rusak, kembalikan trafik ke lingkungan lama. Setelah sistem stabil, baru lakukan analisis akar masalah.

Contoh konfigurasi reverse proxy untuk cutover trafik

Di bawah ini contoh umum dengan Nginx. Intinya, proxy mengarah ke satu upstream aktif. Saat cutover, Anda mengubah target dari blue ke green, lalu reload konfigurasi.

upstream bun_app_blue {
    server 127.0.0.1:3001;
}

upstream bun_app_green {
    server 127.0.0.1:3002;
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://bun_app_blue;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

Saat cutover, proxy_pass dialihkan ke bun_app_green, lalu konfigurasi di-reload. Jika perlu rollback, kembalikan lagi ke bun_app_blue.

Jika Anda memakai load balancer yang mendukung weight atau drain, Anda bisa melakukan peralihan lebih halus. Namun untuk tim kecil, cutover penuh sering lebih mudah dipahami dan dioperasikan.

Catatan tentang koneksi aktif

Saat cutover, pikirkan juga koneksi yang sedang berjalan:

  • untuk request HTTP pendek, efeknya biasanya kecil
  • untuk WebSocket atau koneksi panjang, Anda mungkin perlu strategi drain koneksi sebelum mematikan lingkungan lama
  • atur timeout reverse proxy dengan wajar agar deploy tidak memutus request panjang secara tiba-tiba

Contoh process manager secara umum

Bun bisa dijalankan langsung sebagai proses, tetapi di server produksi biasanya lebih aman memakai process manager atau supervisor agar restart, logging, dan lifecycle proses lebih terkontrol. Tool yang dipilih bisa berbeda-beda, misalnya systemd, Supervisor, PM2, atau mekanisme serupa.

Contoh unit service systemd secara umum:

[Unit]
Description=Bun App Blue
After=network.target

[Service]
WorkingDirectory=/srv/myapp-blue
ExecStart=/usr/bin/bun run server.ts
Environment=PORT=3001
Restart=always
RestartSec=3
User=www-data
Group=www-data

[Install]
WantedBy=multi-user.target

Anda dapat membuat service terpisah untuk blue dan green. Keuntungannya, kedua lingkungan bisa dikelola independen tanpa saling mengganggu.

Checklist pra-deploy

Sebelum release, pastikan checklist ini jelas. Banyak kegagalan deployment bukan karena runtime, melainkan karena langkah operasional yang terlewat.

  • Artefak rilis sudah pasti: commit/tag yang akan dideploy jelas.
  • Konfigurasi environment sinkron: secret, URL service, dan variabel penting benar di lingkungan target.
  • Migration database sudah ditinjau: aman untuk versi lama dan baru selama periode cutover.
  • Endpoint health check tersedia dan benar-benar merepresentasikan kondisi aplikasi.
  • Smoke test siap dijalankan untuk endpoint kritikal.
  • Monitoring dasar aktif: log aplikasi, metrik request, dan alert minimum tersedia.
  • Rencana rollback jelas: siapa yang mengeksekusi, bagaimana cara mengembalikan trafik, dan kondisi pemicunya.
  • Feature flag disiapkan untuk fitur berisiko tinggi.

Migrasi database yang kompatibel mundur

Bagian tersulit dalam blue-green deployment sering bukan aplikasi Bun-nya, melainkan perubahan skema database. Karena versi lama dan baru bisa hidup bersamaan selama transisi, skema harus kompatibel dengan keduanya.

Pola yang relatif aman

  • Expand lalu contract: tambahkan kolom/tabel baru terlebih dahulu, deploy aplikasi yang bisa membaca struktur lama dan baru, baru hapus struktur lama pada release terpisah.
  • Jangan rename langsung kolom yang masih dipakai versi lama.
  • Hindari perubahan destruktif tepat saat cutover, seperti drop kolom atau mengubah constraint secara agresif.
  • Backfill data terpisah dari momen cutover jika prosesnya berat.

Contoh alur aman:

  1. Tambahkan kolom baru yang masih nullable.
  2. Deploy aplikasi baru yang mulai menulis ke kolom lama dan baru bila perlu.
  3. Backfill data lama ke kolom baru.
  4. Alihkan pembacaan ke kolom baru.
  5. Pada release berikutnya, baru hapus kolom lama.

Pendekatan ini memang lebih lambat, tetapi jauh lebih aman untuk rollback. Jika rollback diperlukan, versi lama masih bisa berjalan karena skema belum diubah secara destruktif.

Feature flag dan batas aman rilis bertahap

Blue-green deployment memindahkan versi aplikasi, tetapi tidak harus sekaligus mengaktifkan semua fitur baru. Feature flag membantu memisahkan deploy dari release.

Manfaat feature flag:

  • fitur bisa dimatikan cepat tanpa redeploy
  • risiko perubahan besar dapat dipersempit
  • tim bisa memverifikasi kestabilan versi baru sebelum membuka fitur ke semua pengguna

Untuk tim kecil, aturan sederhana ini cukup membantu:

  • jangan gabungkan perubahan skema, perubahan perilaku bisnis besar, dan refactor besar dalam satu release berisiko tinggi
  • aktifkan fitur baru untuk subset internal lebih dulu bila memungkinkan
  • tetapkan batas aman: jika error rate atau latensi melewati ambang internal, hentikan release dan rollback

Meski Anda tidak punya sistem canary penuh, Anda tetap bisa menerapkan rilis bertahap secara operasional, misalnya dengan membuka fitur hanya untuk admin, tenant tertentu, atau traffic internal.

Observability dasar setelah release

Setelah cutover, jangan hanya melihat apakah server hidup. Anda perlu memantau sinyal yang benar-benar menunjukkan kualitas release.

Metrik minimum yang perlu dipantau

  • Request rate: apakah trafik masuk normal.
  • Error rate: proporsi respons 5xx dan 4xx yang tidak wajar.
  • Latency: terutama p95 atau indikator latensi tinggi secara umum.
  • Restart/crash proses: apakah process manager melakukan restart berulang.
  • Kegagalan koneksi database/cache: timeout, pool habis, autentikasi gagal.
  • Resource host: CPU, memori, disk, dan file descriptor bila relevan.

Log yang penting saat release

  • Log startup: memastikan konfigurasi dan binding port benar.
  • Log error terstruktur: endpoint, status code, request id, dan pesan error.
  • Log dependency failure: database, cache, queue, external API.
  • Log deploy event: versi rilis, waktu cutover, operator, hasil smoke test.

Jika memungkinkan, sertakan release version atau commit SHA pada log dan response header internal. Ini sangat membantu saat membedakan error yang muncul pada blue atau green.

Sinyal rollback yang umum

  • lonjakan 5xx setelah cutover
  • latensi naik tajam pada endpoint kritikal
  • readiness gagal berkali-kali setelah menerima trafik
  • fitur utama tidak lolos verifikasi pasca-release
  • error database yang menunjukkan migrasi tidak kompatibel

Contoh prosedur rollback cepat

Rollback yang baik harus sederhana. Jika prosedurnya terlalu panjang, tim akan terlambat merespons ketika insiden terjadi.

  1. Konfirmasi gejala utama: misalnya error rate meningkat setelah cutover.
  2. Alihkan reverse proxy kembali ke lingkungan lama.
  3. Reload konfigurasi proxy atau aktifkan target lama di load balancer.
  4. Verifikasi health check dan smoke test di lingkungan lama.
  5. Amati apakah metrik kembali normal.
  6. Tahan lingkungan baru untuk investigasi, jangan langsung dihapus.

Yang sering salah adalah melakukan rollback aplikasi, tetapi lupa bahwa perubahan database sudah destruktif. Karena itu, desain migrasi kompatibel mundur adalah syarat penting agar rollback benar-benar cepat dan aman.

Kesalahan umum saat menerapkan blue-green deployment Bun

  • Menganggap proses menyala berarti siap. Tanpa readiness check, proxy bisa mengirim trafik ke instance yang belum siap.
  • Health check terlalu berat. Akibatnya endpoint health sendiri menjadi sumber masalah.
  • Tidak ada smoke test. Readiness 200 belum tentu menjamin endpoint bisnis utama berfungsi.
  • Migration tidak kompatibel rollback. Ini penyebab rollback gagal yang paling mahal.
  • Mematikan lingkungan lama terlalu cepat. Sisakan waktu observasi setelah cutover.
  • Tidak menandai versi rilis pada log. Debugging jadi jauh lebih lambat.

Template runbook deployment singkat

1. Identifikasi environment aktif saat ini (blue/green)
2. Deploy build baru ke environment pasif
3. Start proses Bun pada port target
4. Tunggu /health/ready = 200
5. Jalankan smoke test endpoint kritikal
6. Jika lolos, cutover reverse proxy ke environment baru
7. Pantau error rate, latency, restart, dan log error 10-15 menit
8. Jika gagal, rollback trafik ke environment lama
9. Catat hasil release dan tindak lanjut

Template postmortem ringan bila deployment gagal

Postmortem tidak harus panjang. Yang penting cukup untuk mencegah pengulangan masalah.

Judul insiden:
Waktu kejadian:
Versi/release:
Perubahan utama:
Dampak ke pengguna:
Deteksi awal berasal dari:
Gejala utama:
Akar masalah sementara:
Apakah rollback berhasil? Jika ya, berapa lama:
Faktor yang memperparah:
Apa yang berjalan baik:
Tindakan perbaikan 1-3 item:
Owner dan target waktu:

Untuk tim kecil, format seperti ini sudah cukup efektif selama konsisten diisi setelah insiden.

Kapan blue-green deployment tidak ideal

Meski berguna, strategi ini tidak selalu paling cocok.

  • Kapasitas server terbatas sehingga sulit menjalankan dua lingkungan sekaligus.
  • Aplikasi sangat stateful dan sulit dipindahkan tanpa mengganggu sesi aktif.
  • Migrasi database sangat kompleks dan sulit dijaga kompatibilitasnya.

Dalam situasi seperti itu, rolling deployment atau canary bisa lebih sesuai, meski kompleksitas operasionalnya berbeda. Untuk banyak tim kecil, blue-green tetap menarik karena alurnya mudah dipahami dan rollback-nya cepat selama dependensi utama, terutama database, dikelola dengan disiplin.

Penutup

Blue-green deployment Bun dengan health check dan rollback aman bukan soal tool yang paling canggih, tetapi soal proses release yang bisa diulang dengan konsisten. Jika Anda menyiapkan readiness/liveness check yang tepat, smoke test minimal, cutover trafik yang sederhana, rollback yang jelas, serta observability dasar setelah release, Anda sudah mengurangi sebagian besar risiko deploy yang sering menyebabkan downtime.

Mulailah dari arsitektur sederhana: dua instance Bun, satu reverse proxy, health endpoint yang benar, dan prosedur rollback tertulis. Setelah itu, tambah disiplin pada feature flag, migrasi yang kompatibel mundur, dan monitoring pasca-release. Pendekatan ini realistis diterapkan tim kecil tanpa perlu infrastruktur yang berlebihan.