/ 2menit

Deploy Docker tanpa membiarkan request handler menyentuh host

Memisahkan control plane deployment menjadi lapisan request, worker latar, dan adapter runtime terbatas agar request web tidak pernah mengeksekusi pekerjaan infrastruktur.

Platform deployment adalah program yang menjalankan operasi berhak istimewa atas nama pengguna. Ia menyalakan container, menulis konfigurasi nginx, membuka sesi SSH, dan mengubah record DNS. Semuanya perintah yang ingin dijalankan penyerang.

Bentuk naifnya adalah request handler yang mengerjakan semuanya. POST datang, handler memanggil docker compose up, dan respons menunggu. Desain itu menempatkan eksekusi berhak istimewa di jalur yang sama dengan request HTTP tanpa autentikasi, dan itu tempat yang salah.

Tiga lapisan, satu arah

Control plane terpisah menjadi tiga bagian. Lapisan request memvalidasi input, memeriksa izin, dan memasukkan job ke antrean. Worker latar mengambil job dan menjalankannya. Adapter runtime membungkus perintah berhak istimewa yang sebenarnya, satu per target: Docker, Compose, SSH, Git, DNS, ingress.

Request hanya menulis ke antrean. Worker hanya membaca darinya. Adapter hanya menjalankan apa yang diserahkan worker, dan tiap adapter membuka sekumpulan operasi sempit alih-alih shell umum.

// Handler memasukkan ke antrean; ia tidak pernah mengeksekusi.
queue.enqueue(Job::Deploy { service_id, revision }).await?;

Yang didapat adalah satu titik penyempitan. Izin diperiksa di tempat job dibuat, jadi worker tidak perlu menurunkan ulang apakah pemanggilnya berhak. Permukaan adapter cukup kecil untuk diaudit, karena isinya daftar operasi bernama alih-alih pembangun perintah.

Secret yang tetap terenkripsi

Kredensial untuk host Git, registry, dan penyedia DNS dienkripsi saat disimpan dan didekripsi hanya di dalam worker yang membutuhkannya, selama satu job. Lapisan request tidak pernah memegang kredensial terdekripsi, dan API tidak pernah mengembalikannya.

Batasan itu membentuk API-nya. Tidak ada endpoint yang membaca balik token tersimpan, karena tidak ada lapisan yang bisa menyajikannya dengan aman. Rotasi menulis nilai baru dan nilai lama hilang.

Loopback saja, secara default

Control plane mengikat ke loopback kecuali dikonfigurasi lain secara eksplisit. Tool deployment self-hosted sering dijangkau lewat reverse proxy di mesin yang sama, jadi default yang aman adalah yang tidak bisa dijangkau dari jaringan sama sekali.

Tiap keputusan ini kecil. Bersama-sama, artinya membobol lapisan HTTP tidak langsung menyerahkan host, dan itulah sifat yang penting ketika perangkat lunak ini dirancang berjalan dengan akses setara root.

Rollback adalah bagian dari job, bukan undo

Setiap deploy mencatat revisi yang digantikannya, jadi rollback adalah deploy baru dari revisi yang sudah terbukti, bukan pembalikan deploy terakhir. Pembalikan itu rapuh: ia mengasumsikan tidak ada hal lain yang berubah di antaranya, dan biasanya ada.

Catatan itulah pembedanya. Riwayat deployment yang menyimpan apa yang benar-benar berjalan lebih bernilai daripada tombol revert yang menebak.

Tulisan lain

2 menit

Failover tanpa merusak stream

Memindahkan request ke provider yang sehat itu mudah. Melakukannya setelah token pertama sampai ke klien: itu bagian yang sulit.

  • Rust
  • Streaming
  • Reliability
Baca artikel

2 menit

Satu route, lima jendela

Bagaimana satu route SvelteKit menjadi workspace, dock, papan yang terkunci ke desktop, dan dua jendela on-demand, semuanya membaca database lokal yang sama.

  • Tauri
  • Svelte
  • Desktop
Baca artikel