Mengapa Pembaruan Manual Berhenti Berfungsi Setelah Pengguna Nyata Pertama Anda
Anda memperbaiki bug di laptop. Anda mengunggah file yang telah diubah ke server melalui SCP. Anda me-restart aplikasi. Bug hilang. Sederhana, bukan?
Sekarang bayangkan melakukan itu ketika seratus orang sedang menggunakan aplikasi Anda. Anda tidak bisa restart kapan pun Anda mau — pengguna akan terlempar di tengah sesi. Bayangkan aplikasi Anda berjalan di tiga server untuk menangani lalu lintas. Anda perlu mengunggah file yang sama ke ketiganya, satu per satu. Jika satu server terlewat, beberapa pengguna masih melihat versi yang rusak. Lebih buruk lagi, mereka mungkin melihat error karena kode lama dan baru tercampur dalam permintaan yang sama.
Di sinilah tantangan sebenarnya dari pengiriman perangkat lunak dimulai. Bukan dengan pipeline atau alat, tetapi dengan fakta sederhana bahwa aplikasi terus berubah, dan proses manual tidak bisa mengimbanginya.
Sumber Perubahan yang Sebenarnya
Aplikasi Anda tidak akan selesai setelah rilis pertama. Aplikasi akan terus berkembang. Perubahan datang dari segala arah:
- Bug yang baru muncul setelah pengguna nyata mulai menggunakan fitur tertentu
- Fitur baru yang direncanakan untuk rilis berikutnya
- Perubahan konfigurasi karena server kewalahan menangani lalu lintas yang terus bertambah
- Patch keamanan yang harus segera dikirim
Setiap perubahan ini harus mencapai tempat di mana aplikasi Anda berjalan. Dan harus dilakukan berulang kali, selama masih ada orang yang menggunakan aplikasi Anda.
Jebakan Konsistensi Build
Berikut adalah skenario yang terjadi di tim setiap hari. Anda memperbaiki bug di laptop. Perbaikan berfungsi sempurna di lingkungan lokal Anda. Anda mengunggah file ke server, restart, dan... aplikasi crash.
Apa yang terjadi? Mungkin laptop Anda memiliki versi library yang berbeda. Mungkin Anda lupa memperbarui file konfigurasi yang hanya ada di server. Mungkin Anda mengompilasi kode dengan pengaturan yang berbeda. Perbaikan berfungsi di mesin Anda, tetapi lingkungan server sedikit berbeda.
Sekarang Anda terjebak melakukan debug mengapa lingkungan produksi berperilaku berbeda dari pengaturan lokal Anda. Anda memperbaiki masalah, unggah lagi, dan berharap kali ini berhasil. Tetapi ketidakpastian yang sama muncul kembali setiap kali ada perubahan manual.
Ini bukan tentang kecerobohan. Ini tentang ketidakandalan mendasar dari proses manual ketika diulang dari waktu ke waktu. Setiap kali Anda membangun secara manual, ada kemungkinan kecil terjadi sesuatu yang sedikit berbeda. Satu perbedaan saja sudah cukup untuk merusak aplikasi yang sedang berjalan.
Titik Buta Pengujian
Pengujian manual memiliki masalah yang sama. Saat Anda menguji perubahan secara manual, Anda harus mengingat setiap langkah yang Anda lakukan sebelumnya. Apakah Anda memeriksa alur login? Apakah Anda memverifikasi fitur yang mungkin terpengaruh oleh perubahan kecil ini? Apakah Anda menguji kasus batas yang menyebabkan masalah bulan lalu?
Semakin sering Anda memperbarui, semakin besar kemungkinan Anda melewatkan langkah pengujian. Dan ketika Anda melewatkan satu langkah, bug lolos ke produksi. Bukan karena Anda malas, tetapi karena ingatan manusia tidak dirancang untuk mengulangi urutan puluhan langkah dengan sempurna setiap saat.
Mimpi Buruk Multi-Server
Mari kita kembali ke skenario tiga server. Bahkan jika Anda berhasil mengunggah file yang sama ke semua server, Anda sekarang memiliki masalah waktu. Saat Anda mengunggah ke server dua, server satu sudah menjalankan kode baru dan server tiga masih menggunakan kode lama. Pengguna diarahkan ke server yang berbeda tergantung pada beban, yang berarti mereka mungkin melihat versi aplikasi yang berbeda dalam sesi yang sama.
Berikut adalah tampilan pembaruan manual dalam praktik:
# Unggah manual ke setiap server, satu per satu
scp app.jar user@server1.example.com:/opt/app/
ssh user@server1.example.com 'systemctl restart app'
scp app.jar user@server2.example.com:/opt/app/
ssh user@server2.example.com 'systemctl restart app'
scp app.jar user@server3.example.com:/opt/app/
ssh user@server3.example.com 'systemctl restart app'
Sekarang bayangkan Anda memiliki sepuluh server, atau Anda lupa server mana yang sudah diperbarui. Perulangan skrip sederhana mengurangi risiko:
# Perulangan skrip - lebih sedikit ruang untuk kesalahan
for server in server1 server2 server3; do
scp app.jar "user@$server.example.com:/opt/app/"
ssh "user@$server.example.com" 'systemctl restart app'
done
Bahkan skrip kecil ini menghilangkan kemungkinan melewatkan server atau me-restart dalam urutan yang salah. Tetapi masih bergantung pada Anda untuk mengingat menjalankannya dan memiliki file yang benar secara lokal.
Ketidakkonsistenan ini menciptakan bug yang hampir mustahil untuk direproduksi. Seorang pengguna melaporkan masalah, tetapi pada saat Anda melihat log, semua server sudah pada versi yang sama. Masalahnya hilang, tetapi Anda tidak tahu mengapa. Dan itu akan kembali pada pembaruan manual berikutnya.
Mengapa Konsistensi Menjadi Non-Negotiable
Pada titik ini, polanya menjadi jelas. Proses manual tidak konsisten. Setiap kali Anda membangun, menguji, atau menyebarkan secara manual, ada kemungkinan kecil variasi. Satu variasi dalam proses build, satu pengujian terlewat, satu server terlewat — salah satu dari ini dapat menyebabkan masalah. Dan ketika Anda sering memperbarui, probabilitas setidaknya satu variasi terjadi mendekati kepastian.
Ini bukan tentang menjadi malas atau ingin mengotomatisasi demi otomatisasi. Ini tentang menyadari bahwa proses manual tidak dapat memberikan konsistensi yang dibutuhkan oleh aplikasi langsung. Pengguna Anda tidak peduli bahwa Anda memiliki hari yang panjang dan lupa menguji satu skenario. Mereka hanya peduli bahwa aplikasi berfungsi.
Konsistensi berarti:
- Setiap build menghasilkan hasil yang sama, kecuali untuk kode yang benar-benar berubah
- Setiap proses pengujian mencakup skenario yang sama dengan cara yang sama
- Setiap deployment mengikuti langkah yang sama di setiap server
Pergeseran Praktis
Ini adalah momen di mana tim mulai mencari cara untuk menstandarisasi proses build, pengujian, dan deployment mereka. Bukan karena mereka membaca tentang CI/CD di posting blog, tetapi karena mereka merasakan sakitnya pembaruan manual yang tidak konsisten. Mereka mengalami sesi debugging larut malam yang disebabkan oleh file konfigurasi yang terlupakan. Mereka menangani keluhan pengguna yang berasal dari server yang terlewat.
Pergeseran terjadi ketika Anda menyadari bahwa proses manual tidak hanya lambat — mereka tidak dapat diandalkan untuk pekerjaan yang berulang. Dan aplikasi Anda akan selalu membutuhkan pembaruan berulang, selama masih ada bug yang perlu diperbaiki, fitur yang perlu ditambahkan, atau konfigurasi yang perlu diubah.
Pemeriksaan Konsistensi Cepat
Sebelum Anda mengotomatiskan apa pun, periksa apakah Anda memiliki dasar-dasar ini:
- Dapatkah Anda membangun ulang versi aplikasi yang sama persis dari awal, di mesin mana pun?
- Apakah Anda tahu persis file mana yang berubah antara versi saat ini dan versi sebelumnya?
- Dapatkah Anda memverifikasi bahwa semua server Anda menjalankan versi yang sama saat ini?
- Apakah Anda memiliki proses deployment tertulis, langkah demi langkah, yang dapat diikuti oleh orang lain?
Jika jawaban untuk salah satu dari ini adalah tidak, mulailah dari sana. Alat dan pipeline datang kemudian. Konsistensi adalah yang utama.
Apa Artinya Ini Bagi Tim Anda
Lain kali Anda melakukan deployment manual, perhatikan setiap langkah yang Anda ambil. Perhatikan keputusan kecil yang Anda buat tanpa berpikir — file mana yang akan diunggah terlebih dahulu, server mana yang akan diperbarui terakhir, pengujian mana yang akan dijalankan. Keputusan kecil itulah tempat ketidakkonsistenan bersembunyi.
Tujuan Anda bukan untuk menghilangkan semua pekerjaan manual dalam semalam. Ini untuk menyadari bahwa proses manual memiliki batas. Mereka bekerja dengan baik untuk satu server dan satu pengembang. Mereka rusak ketika Anda memiliki beberapa server, beberapa lingkungan, dan beberapa pembaruan per minggu. Kerusakan itu bukanlah kegagalan — itu adalah sinyal bahwa proses pengiriman Anda perlu berkembang seiring dengan aplikasi Anda.