Pengantar: Menyelesaikan Deployment Express.js dengan Aman

Untuk menjalankan Express.js di produksi, yang paling penting adalah memastikan pipeline yang jelas, observabilitas yang cukup, serta kemampuan rollback terukur. Artikel ini langsung membahas bagaimana mempersiapkan pipeline yang mencakup build, lint, dan smoke test, menerapkan strategi deployment bertahap (fitur flag, canary, blue-green), menjaga observabilitas, mengeksekusi rollback, serta melakukan postmortem dan proactive health check.

Setiap langkah dirancang agar bisa diterapkan dalam lingkungan DevOps nyata, sehingga Anda bisa mengurangi risiko gangguan layanan saat memperbarui backend Express.

Persiapan Pipeline: Build, Lint, dan Smoke Test

Pertama, pastikan pipeline CI/CD Anda mengekspos tahapan build, lint, dan smoke test sebelum artefak didorong ke staging atau produksi. Contoh konfigurasi GitHub Actions berikut menampilkan urutan: instal dependencies, lint, build (jika ada bundler), lalu smoke test ringan dengan server lokal.

name: Deploy Express.js
on: [push]
jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies
        run: npm ci
      - name: Lint source
        run: npm run lint
      - name: Build (optional)
        run: npm run build
      - name: Smoke test
        run: npm run smoke-test

Pastikan package.json memiliki skrip yang ditujukan untuk tiap tahap. Misalnya, npm run lint bisa menjalankan ESLint dengan konfigurasi yang memeriksa aturan API, sedangkan smoke-test menjalankan skrip kecil yang memanggil endpoint /health setelah server berjalan.

Smoke test bertujuan memverifikasi bahwa server memulai dan bisa menjawab request dasar tanpa menunggu integrasi penuh. Karena itu, gunakan mock ringan jika API bergantung pada service lain.

Strategi Deployment Incremental

Setelah pipeline siap, Anda perlu menentukan bagaimana versi baru akan diluncurkan. Strategi incremental membantu meminimalkan dampak dan memberikan titik kontrol sebelum menggantikan seluruh layanan.

Feature Flag

Implementasi feature flag (misalnya dengan launchdarkly atau utilitas internal) memungkinkan mengaktifkan fitur baru hanya untuk subset pengguna. Dalam Express.js, gunakan middleware yang memeriksa flag pada request sebelum mengeksekusi route baru. Misalnya:

app.get('/beta-route', (req, res, next) => {
  if (!featureToggle.isActive('beta-route')) {
    return res.status(404).send('Not found');
  }
  next();
}, betaRouteHandler);

Perhatikan: flag harus bisa diubah tanpa redeploy untuk menutup fitur jika terjadi masalah.

Canary Deployment

Canary berarti sebagian kecil traffic dialihkan ke versi baru. Untuk Express.js yang dijalankan lewat container/kubernetes, Anda bisa gunakan Deployment dengan maxSurge rendah dan maxUnavailable tinggi, lalu isi Service dengan traffic-split (misalnya Istio atau Traefik). Targetkan observability metrics untuk canary, misalnya error rate, latency, atau DB errors. Jika metrik tetap stabil, tingkatkan trafik secara bertahap.

Blue-Green

Blue-green sangat berguna jika infrastruktur sudah mendukung switch instant (misalnya load balancer). Pastikan komponen stateful (session, cache) sinkron antara versi biru dan hijau. Setelah versi hijau melewati smoke test dan observability baseline, alihkan traffic via switch load balancer. Simpan versi biru untuk rollback cepat.

Observabilitas Utama

Observabilitas memberikan visibility atas sistem setelah deployment. Fokus pada tiga dimensi: metrics, tracing, dan log context.

Metrics

Gunakan library seperti prom-client untuk mengukur request rate, error rate, latency, dan health checks. Contoh dasar middleware metrics:

const promClient = require('prom-client');
const httpRequestDuration = new promClient.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Durasi request HTTP',
  labelNames: ['method', 'route', 'status_code'],
});

app.use((req, res, next) => {
  const end = httpRequestDuration.startTimer();
  res.on('finish', () => end({ method: req.method, route: req.route?.path || req.path, status_code: res.statusCode }));
  next();
});

Ekspos metrics ke Prometheus di endpoint /metrics dan pastikan alertumen memantau error rate > threshold selama canary.

Tracing

Implementasi OpenTelemetry memungkinkan pelacakan lintas service. Gunakan SDK Node untuk Express, instrumentasi middleware, dan kirim span ke backend seperti Jaeger/Tempo. Ini membantu memperlihatkan apakah versi baru menyebabkan peningkatan latency downstream.

Log Context

Sertakan trace id/ request id di log sehingga Anda bisa korelasi dengan trace dan metrics. Contoh middleware menambahkan req.id ke log:

const { v4: uuid } = require('uuid');
app.use((req, res, next) => {
  req.id = uuid();
  console.log(`[${req.id}] ${req.method} ${req.path}`);
  res.on('finish', () => console.log(`[${req.id}] status ${res.statusCode}`));
  next();
});

Recoer log context ini ke sistem log terpusat (ELK, Loki, dsb.) untuk troubleshooting cepat.

Prosedur Rollback Terukur

Rollback harus menjadi langkah terukur, bukan panik. Siapkan playbook dengan langkah berikut:

  1. Identifikasi trigger: error rate > 5%, latency naik 2x, atau smoke test gagal.
  2. Kunci deployment baru (disable flag/canary) agar tidak ada further traffic.
  3. Kembalikan route ke versi sebelumnya (blue-green switch atau scale down canary).
  4. Catat penyebab di log postmortem dan hubungkan dengan commit yang dikembalikan.
  5. Verifikasi rollback dengan same metrics dan smoke test.

Rollback yang terukur harus didukung oleh observability: saat rollback, pantau metrics sama seperti saat deploy. Jika rollback melibatkan DB schema, siapkan migrasi balik yang teruji sebelumnya.

Checklist Pasca-Inciden Ringan

Setelah insiden kecil (misalnya latency sementara), ikuti checklist:

  • Postmortem ringkas: tuangkan apa yang terjadi, timeline, dan keputusan rollback (Jika tidak rollback, jelaskan mitigasi).
  • Identifikasi root cause dari observability data (metrics, trace, logs).
  • Tindakan pencegahan: perbaiki script lint/build, tambahkan test, tingkatkan alert.
  • Publikasi: bagikan hasil dengan tim lewat channel komunikasi agar pembelajaran tersebar.

Pastikan postmortem menyertakan tugas lanjutan (misalnya memperbarui dokumentasi deployment atau menambah unit test validator). Proses ini memperkaya playbook rollback dan meningkatkan readiness.

Menjaga Health Check Secara Proaktif

Health check membentengi deployment. Sediakan endpoint /health yang mengeluarkan status dari dependensi utama (database, cache, message broker). Pastikan layanan load balancer memanggil endpoint ini secara rutin.

Selain itu, jalankan health check terpadu di pipeline sebagai bagian dari smoke test. Health check sebaiknya memeriksa: koneksi database, latency ke queue broker, dan resource usage saat idle. Informasi ini membantu memutuskan apakah server siap menerima trafik.

Dalam monitoring, buat alert untuk health check yang gagal lebih dari 3 kali berturut-turut. Jika terjadi, hentikan deployment atau jalankan rollback otomatis agar versi stabil tetap melayani pelanggan.