Blueprint deployment Git Service yang baik bukan berarti pipeline paling kompleks, melainkan rilis yang bisa dihentikan cepat, dibalikkan dengan aman, dan dievaluasi tanpa drama setelah insiden. Untuk layanan mirip Git forge atau self-hosted code hosting, kegagalan kecil saat rilis bisa berdampak besar: push gagal, web UI error, webhook tertunda, runner macet, sampai migrasi database yang mengunci operasi penting.

Dalam konteks tren operasional yang terlihat pada laporan bulanan Forgejo Mei 2026, pelajaran yang relevan bukan mengejar fitur baru semata, tetapi membangun proses rilis yang tahan gangguan dan mudah dioperasikan. Artikel ini fokus pada praktik yang realistis untuk tim DevOps: canary atau blue-green sederhana, health check yang benar, migrasi skema yang masih kompatibel saat rollback, backup singkat sebelum rilis, observability minimum, runbook rollback, dan postmortem ringan agar rilis berikutnya lebih aman.

Karakteristik layanan Git yang membuat deployment lebih sensitif

Layanan Git self-hosted biasanya bukan hanya satu web app. Di dalamnya ada beberapa jalur kritis yang perlu tetap sehat selama rilis:

  • HTTP UI dan API untuk login, browsing repo, issue, PR, admin, webhook.
  • Git over HTTP/SSH untuk clone, fetch, push.
  • Background job untuk indexing, notifikasi, mirror, webhook delivery, housekeeping.
  • Database sebagai sumber data utama untuk user, repo metadata, session, issue, dan konfigurasi.
  • Storage untuk repository, attachment, package, LFS, atau artefak lain.

Artinya, health check tidak boleh berhenti di level “port terbuka” atau “HTTP 200 dari /login”. Anda perlu memastikan bahwa jalur operasi inti benar-benar bekerja, minimal pada level readiness dan sinyal operasional dasar.

Blueprint deployment Git Service yang aman dan tetap sederhana

Untuk mayoritas tim, target yang masuk akal adalah:

  1. Rilis bisa dilakukan bertahap.
  2. Rollback bisa selesai cepat tanpa improvisasi.
  3. Perubahan skema database tidak memaksa rollback menjadi mustahil.
  4. Ada sinyal objektif kapan rollout diteruskan, dihentikan, atau dibalik.

Pilih canary atau blue-green sesuai kompleksitas sistem

Canary cocok jika Anda punya beberapa instance aplikasi di belakang load balancer. Satu instance baru menerima sebagian kecil trafik lebih dulu. Keuntungannya, risiko awal kecil dan verifikasi terjadi pada trafik nyata. Kekurangannya, Anda harus hati-hati jika ada perubahan stateful, cache, atau migrasi yang belum sepenuhnya kompatibel antara versi lama dan baru.

Blue-green cocok jika Anda ingin pemisahan lebih jelas antara lingkungan lama dan baru. Lingkungan green disiapkan penuh, diuji, lalu trafik dialihkan. Keuntungannya rollback biasanya lebih cepat karena cukup mengembalikan routing. Kekurangannya, biaya resource lebih tinggi dan sinkronisasi state perlu dipikirkan.

Untuk layanan Git internal, pendekatan yang sering paling realistis adalah:

  • Blue-green untuk komponen web/API jika infrastruktur memungkinkan.
  • Rolling/canary hati-hati untuk worker/background job.
  • Storage dan database tetap shared, tetapi perubahan skema dibuat kompatibel lintas versi.

Catatan: Jika database dan storage tetap dipakai bersama oleh versi lama dan baru, maka desain migrasi jauh lebih penting daripada metode switch trafik.

Arsitektur referensi sederhana

Users / CI / Developers
        |
   Load Balancer
     /       \
  blue      green
   |           |
web+api     web+api
   \         /
    shared database
    shared repo storage
    shared object storage (opsional)
    shared metrics/logging

Pada model ini, rollout aman bergantung pada tiga hal:

  • Instance baru hanya dianggap siap jika readiness check lulus.
  • Migrasi skema tidak memutus kompatibilitas versi lama.
  • Rollback routing bisa dilakukan tanpa menunggu perubahan data yang irreversible.

Health check yang benar: liveness, readiness, dan smoke test

Liveness tidak cukup

Liveness hanya menjawab: “proses masih hidup?”. Ini berguna untuk restart otomatis, tetapi tidak cukup untuk deployment gate. Aplikasi bisa hidup namun gagal melayani push karena koneksi database habis, queue macet, atau storage tidak bisa ditulis.

Readiness harus memeriksa dependensi minimum

Untuk Git service, readiness idealnya mencakup:

  • Koneksi ke database tersedia dan query ringan berhasil.
  • Akses ke storage repo atau object storage tersedia jika dibutuhkan untuk request normal.
  • Worker internal atau komponen penting yang diperlukan untuk request sinkron berada dalam keadaan siap.
  • Cache atau session store, jika kritikal, dapat diakses.

Jangan buat readiness terlalu berat. Tujuannya adalah memastikan instance aman menerima trafik, bukan menjalankan test end-to-end penuh setiap beberapa detik.

Tambahkan smoke test setelah instance siap

Setelah readiness lulus, jalankan smoke test singkat dari pipeline atau job operasional. Untuk layanan Git, contoh smoke test yang berguna:

  • Login atau akses endpoint API yang butuh autentikasi service account.
  • Baca metadata satu repo uji.
  • Clone atau fetch repo kecil uji.
  • Buat dan hapus branch pada repo uji non-produksi bila prosedur Anda mengizinkan.
  • Kirim webhook uji dan pastikan terkirim.

Contoh shell script smoke test sederhana:

#!/usr/bin/env sh
set -eu

BASE_URL="https://git.example.internal"
TOKEN="${SMOKE_TOKEN}"
REPO_URL="${SMOKE_REPO_URL}"
WORKDIR="$(mktemp -d)"

cleanup() {
  rm -rf "$WORKDIR"
}
trap cleanup EXIT

# 1) API check
curl -fsS -H "Authorization: token $TOKEN" \
  "$BASE_URL/api/v1/user" > /dev/null

# 2) Clone/fetch check
cd "$WORKDIR"
git clone --quiet "$REPO_URL" repo
cd repo
git fetch --quiet origin

echo "smoke test passed"

Script di atas sengaja sederhana. Nilai utamanya adalah memverifikasi jalur yang benar-benar dipakai pengguna, bukan hanya endpoint status internal.

Migrasi skema yang tetap kompatibel saat rollback

Rollback paling sering gagal bukan karena container image lama hilang, tetapi karena database sudah berubah dengan cara yang tidak bisa dibaca versi lama. Karena itu, untuk deployment Git service, prioritaskan migrasi yang kompatibel dengan strategi expand and contract.

Pola expand and contract

  1. Expand: tambahkan kolom/tabel/index baru tanpa menghapus yang lama.
  2. Deploy aplikasi baru yang bisa membaca format lama dan baru, atau minimal masih aman jika rollback ke versi lama.
  3. Backfill data secara bertahap jika diperlukan.
  4. Contract: hapus kolom/perilaku lama hanya setelah beberapa rilis dan yakin rollback tidak lagi dibutuhkan.

Contoh perubahan yang relatif aman:

  • Menambah kolom nullable baru.
  • Menambah tabel baru yang belum dibaca versi lama.
  • Menambah index untuk query yang akan dipakai versi baru.

Contoh perubahan berisiko tinggi:

  • Mengganti nama kolom yang masih dipakai versi lama.
  • Mengubah tipe data secara langsung tanpa kompatibilitas baca.
  • Menghapus kolom atau constraint yang masih diasumsikan aplikasi lama.
  • Migrasi besar yang mengunci tabel kritis saat trafik puncak.

Strategi praktis untuk migrasi aman

  • Pisahkan migrasi skema dan migrasi data berat. Jangan gabungkan perubahan DDL dan backfill masif dalam satu langkah rilis.
  • Jalankan index creation secara hati-hati sesuai kemampuan database Anda agar tidak menahan trafik terlalu lama.
  • Hindari default mahal pada tabel besar jika database Anda akan menulis ulang banyak baris.
  • Simpan feature flag untuk perilaku baru yang bergantung pada skema tambahan.
  • Uji rollback pada environment staging dengan snapshot data yang representatif.

Prinsip utama: versi lama harus tetap bisa berjalan beberapa waktu di atas skema yang sudah diperluas, setidaknya cukup lama untuk rollback terkendali.

Backup singkat sebelum rilis: kecil, cepat, dan terukur

Tidak semua rilis butuh backup penuh. Namun untuk layanan Git, ada baiknya punya backup singkat sebelum rilis yang disesuaikan dengan risiko perubahan.

Apa yang perlu dibackup sebelum rilis

  • Snapshot database atau backup logis terbatas sebelum migrasi.
  • Konfigurasi aplikasi dan secret reference jika ada perubahan config.
  • Metadata penting yang sulit direkonstruksi cepat jika migrasi bermasalah.

Repository Git sendiri sering kali sudah memiliki ketahanan lebih baik karena objek bersifat append-heavy dan bisa direplikasi terpisah. Tetapi metadata DB, konfigurasi auth, token, webhook, issue, package registry, dan state worker sering kali menjadi bagian paling sensitif saat rilis.

Trade-off backup sebelum rilis

  • Backup penuh memberi rasa aman lebih tinggi, tetapi bisa memperpanjang maintenance window.
  • Snapshot cepat lebih realistis untuk rilis rutin, tetapi harus diuji restore-nya.

Kesalahan umum adalah menganggap “backup ada” padahal restore tidak pernah diuji. Untuk tujuan rollback cepat, kemampuan restore dan kejelasan prosedur lebih penting daripada sekadar keberadaan file backup.

Observability minimum untuk keputusan rollout dan rollback

Anda tidak butuh platform observability yang rumit untuk membuat deployment lebih aman. Tetapi Anda perlu sinyal minimum yang bisa dipercaya.

Log yang wajib mudah dicari

  • Error aplikasi per request.
  • Error autentikasi ke database, cache, storage.
  • Gagal push/pull/clone via HTTP atau SSH.
  • Job background yang gagal atau retry terus-menerus.
  • Webhook delivery gagal.

Gunakan field terstruktur bila memungkinkan: timestamp, service, instance, request path, status code, latency, error class, repo atau tenant identifier jika aman.

Metric minimum yang berguna

  • Request rate per jalur utama: UI/API, Git HTTP, SSH bila tersedia.
  • Error rate 5xx dan error domain-spesifik seperti auth failure atau push failure.
  • Latency p95 atau p99 untuk endpoint penting.
  • Queue depth dan age untuk background jobs.
  • Database connection usage dan slow query signal.
  • Storage error count atau timeout.

SLI minimum untuk Git service

SLI tidak harus banyak. Mulai dari yang benar-benar mempengaruhi pengguna:

  • Ketersediaan operasi read: persentase request browse/API sukses.
  • Ketersediaan operasi write: persentase push atau write API sukses.
  • Latency operasi inti: waktu respons untuk login, halaman repo, API penting, atau clone/fetch repo uji kecil.
  • Ketepatan background delivery: webhook atau job penting selesai dalam rentang waktu yang diterima.

Alert minimum sebelum rollout dianggap gagal

  • Lonjakan 5xx setelah satu instance baru menerima trafik.
  • Kenaikan latency tajam pada endpoint repo/API.
  • Peningkatan gagal autentikasi internal ke DB/storage.
  • Queue backlog tumbuh terus setelah deploy worker baru.
  • Push/fetch smoke test gagal dua kali berturut-turut.

Runbook rollback yang bisa dipakai saat tekanan tinggi

Rollback harus ditulis sebagai prosedur operasional, bukan pengetahuan yang hanya ada di kepala satu engineer. Saat insiden berlangsung, runbook yang singkat dan tegas jauh lebih berguna daripada dokumentasi panjang yang ambigu.

Kapan rollback harus dipicu

Gunakan sinyal yang terukur. Contohnya:

  • Smoke test pasca-deploy gagal dan penyebabnya tidak jelas dalam beberapa menit pertama.
  • Error rate meningkat konsisten setelah canary aktif.
  • Request write penting seperti push atau webhook delivery gagal pada jalur baru.
  • Readiness flapping pada instance baru.
  • Migrasi menyebabkan lock, timeout, atau antrian job meningkat cepat.
  • Perilaku data terlihat korup atau tidak konsisten.

Prinsip praktisnya: jika waktu diagnosis mulai lebih lama daripada waktu rollback, rollback dulu. Deployment bukan tempat terbaik untuk investigasi panjang di produksi.

Template runbook rollback

  1. Tentukan scope: apakah hanya web/API, worker, atau termasuk migrasi data.
  2. Hentikan rollout: pause pipeline atau nonaktifkan step otomatis berikutnya.
  3. Kembalikan trafik ke versi lama atau kurangi weight canary ke nol.
  4. Skalakan turun instance baru agar tidak menerima trafik tersisa.
  5. Verifikasi health pada versi lama dengan smoke test utama.
  6. Tinjau database: pastikan migrasi masih kompatibel. Jangan buru-buru rollback skema tanpa analisis dampak.
  7. Komunikasikan status ke kanal insiden dan stakeholder internal.
  8. Simpan artefak bukti: log, metric, waktu, commit, image, perubahan config.

Contoh rollback routing sederhana

# Pseudocode - sesuaikan dengan load balancer/proxy Anda
# 1) Stop receiving new traffic on green
set_backend_weight green 0
set_backend_weight blue 100

# 2) Verify user-facing checks
run_smoke_tests --target blue

# 3) Stop green workers if they may continue mutating shared state
scale_workers green 0

# 4) Mark release as rolled back
annotate_deployment --status rolled_back --reason "elevated 5xx"

Jika ada migrasi data non-kompatibel yang sudah berjalan, rollback aplikasi mungkin belum cukup. Karena itu, lebih aman mencegah kondisi ini sejak desain awal daripada bergantung pada rollback skema darurat.

Checklist praktis: pra-rilis, saat rilis, dan pasca-rilis

Checklist pra-rilis

  • Perubahan sudah ditandai: aplikasi saja, config, worker, migrasi skema, atau kombinasi.
  • Migrasi database ditinjau untuk kompatibilitas rollback.
  • Image/artifact rilis sudah immutable dan bisa di-redeploy.
  • Feature flag untuk perilaku berisiko tinggi sudah disiapkan.
  • Backup singkat atau snapshot sebelum rilis telah dibuat dan diverifikasi selesai.
  • Dashboard metric dan query log untuk rilis ini sudah siap.
  • Smoke test otomatis tersedia dan kredensial uji valid.
  • On-call engineer dan PIC rilis ditentukan.
  • Maintenance note internal siap jika rollback diperlukan.
  • Perubahan dilakukan di jam dengan risiko operasional terukur, bukan saat beban puncak.

Checklist saat rilis

  • Catat waktu mulai, versi/commit, dan operator.
  • Jalankan migrasi aman lebih dulu bila memang perlu.
  • Deploy ke canary atau green environment.
  • Tunggu readiness benar-benar stabil, bukan hanya sesaat hijau.
  • Jalankan smoke test read dan write path.
  • Amati log error, 5xx, latency, queue, dan koneksi DB.
  • Naikkan porsi trafik bertahap jika metrik stabil.
  • Hentikan rollout jika ada sinyal rollback yang telah disepakati.

Checklist pasca-rilis

  • Pastikan semua instance berada di versi target.
  • Verifikasi worker dan webhook backlog normal.
  • Periksa error rate dan latency 15-30 menit setelah rilis.
  • Catat deviasi, workaround, atau gejala kecil meskipun belum menjadi insiden.
  • Arsipkan log rilis, dashboard snapshot, dan hasil smoke test.
  • Jika terjadi gangguan, jadwalkan postmortem ringan maksimal 1-2 hari kerja setelahnya.

Template timeline insiden untuk deployment bermasalah

Timeline membantu memisahkan fakta dari asumsi. Formatnya tidak perlu panjang, yang penting konsisten.

Insiden: Gagal deploy Git service - peningkatan 5xx dan push failure
Tanggal: 2026-05-XX
Owner: Nama PIC

[10:02] Deploy dimulai ke green environment
[10:05] Readiness green lulus
[10:07] Smoke test API sukses
[10:09] Canary traffic 10% diarahkan ke green
[10:11] Alert: 5xx rate naik pada endpoint repo API
[10:12] Laporan internal: push via HTTP gagal intermiten
[10:13] Rollout dihentikan
[10:15] Canary weight dikembalikan ke 0%, blue 100%
[10:17] Smoke test pada blue sukses
[10:22] Error rate kembali normal
[10:40] Investigasi awal: koneksi storage pada green salah konfigurasi
[11:30] Insiden ditutup, postmortem dijadwalkan

Timeline seperti ini memudahkan analisis apakah masalah muncul setelah perubahan aplikasi, setelah trafik dialihkan, atau setelah worker aktif.

Postmortem ringan: cukup untuk belajar, tidak memberatkan tim

Postmortem ringan cocok untuk tim yang ingin disiplin belajar dari insiden tanpa membuat proses menjadi birokratis. Tujuannya bukan mencari siapa yang salah, melainkan mengurangi kemungkinan pengulangan.

Struktur postmortem ringan

  • Ringkasan insiden: apa yang terjadi dan dampaknya.
  • Timeline: urutan fakta penting.
  • Deteksi: bagaimana insiden diketahui, otomatis atau laporan pengguna.
  • Akar masalah teknis: bug, config, migrasi, kapasitas, dependency, atau gap observability.
  • Faktor kontribusi: checklist terlewat, test kurang representatif, readiness terlalu dangkal.
  • Apa yang berjalan baik: rollback cepat, alert tepat, backup tersedia.
  • Apa yang perlu diperbaiki: tindakan nyata dan owner yang jelas.

Contoh template singkat

Judul: Rollback deployment Git service karena push failure pada environment baru
Tanggal: 2026-05-XX
Severity: internal / sedang

Ringkasan:
Rilis versi baru menyebabkan sebagian request push via HTTP gagal setelah 10% trafik masuk ke green.
Rollback dilakukan dalam 6 menit sejak alert pertama.

Dampak:
- Push gagal intermiten untuk sebagian pengguna
- Tidak ada kehilangan data terkonfirmasi
- Web UI tetap sebagian besar tersedia

Akar masalah teknis:
Environment green memiliki konfigurasi storage backend yang tidak lengkap,
sehingga operasi write tertentu gagal meskipun readiness dasar lulus.

Faktor kontribusi:
- Readiness tidak memeriksa write access ke storage
- Smoke test hanya memverifikasi API read dan clone/fetch
- Checklist config parity antar environment belum eksplisit

Yang berjalan baik:
- Canary membatasi blast radius
- Alert 5xx aktif dan cepat memicu investigasi
- Runbook rollback jelas dan berhasil

Tindakan pencegahan:
- Tambah smoke test write path pada repo uji
- Tambah verifikasi config parity sebelum switch traffic
- Perluas readiness atau preflight check untuk storage write access
Owner: ...  Due: ...

Tindakan pencegahan agar rilis berikutnya lebih aman

Nilai utama postmortem adalah daftar perbaikan yang kecil tetapi efektif. Berikut tindakan yang biasanya memberi dampak besar untuk deployment Git service:

  • Tambahkan smoke test write path, bukan hanya read path.
  • Buat checklist parity config antara blue dan green, terutama storage, auth, webhook, URL publik, dan secret mapping.
  • Pisahkan deploy web dan worker jika worker bisa memproses state baru yang belum siap ditangani versi lama.
  • Gunakan feature flag untuk fitur berisiko agar deploy dan aktivasi fitur tidak harus bersamaan.
  • Latih rollback secara berkala pada staging atau game day internal.
  • Tambahkan deployment annotation ke dashboard observability agar lonjakan error mudah dikorelasikan dengan rilis.
  • Tinjau migrasi besar sebagai perubahan tersendiri, bukan “sekalian” dalam rilis aplikasi rutin.
  • Pastikan artefak rilis immutable sehingga redeploy versi sebelumnya tidak bergantung pada build ulang.

Kesalahan umum yang perlu dihindari

  • Mengandalkan health check yang hanya memeriksa HTTP 200 dari endpoint statis.
  • Menganggap rollback aplikasi selalu cukup, padahal skema DB sudah tidak kompatibel.
  • Menjalankan migrasi berat di jam sibuk tanpa observability yang memadai.
  • Mengaktifkan 100% trafik terlalu cepat karena “instance sudah running”.
  • Tidak memisahkan sinyal read path dan write path.
  • Tidak mencatat waktu kejadian, sehingga analisis insiden menjadi spekulatif.

Penutup

Blueprint deployment Git Service yang aman bisa dibangun tanpa platform yang berlebihan. Fondasinya adalah rollout bertahap, health check yang relevan, migrasi skema yang kompatibel rollback, backup singkat sebelum rilis, observability minimum yang bisa dipercaya, runbook rollback yang ringkas, dan postmortem ringan yang menghasilkan tindakan nyata.

Jika Anda hanya ingin memulai dari sedikit perubahan, prioritaskan tiga hal: smoke test untuk jalur push/fetch nyata, canary atau blue-green sederhana, dan aturan rollback yang jelas. Tiga hal itu saja sudah cukup menurunkan risiko rilis layanan Git self-hosted secara signifikan.