FreeBSD Jails vs Docker Containers: Apa Bedanya?
Jail menjalankan userland FreeBSD lengkap, sedangkan Docker menjalankan proses dari image berlapis. Bandingkan software, state, jaringan, dan batas isolasinya.
FreeBSD jails vs Docker containers, dalam satu paragraf
FreeBSD jails dan Docker containers menyelesaikan masalah yang sama dengan dua bentuk berbeda. Keduanya menjalankan userland yang terisolasi pada satu kernel bersama, sehingga tidak satu pun merupakan virtual machine. Perbedaannya terletak pada isi lingkungan tersebut. Docker container menjalankan satu proses dari image berlapis yang Anda ambil dari registry. Jail menjalankan userland FreeBSD lengkap: /etc miliknya sendiri, skrip startup rc miliknya sendiri, database pkg miliknya sendiri, serta proses sebanyak yang Anda perlukan. Hampir semua perbedaan lain di halaman ini berasal dari hal tersebut.
SSD Nodes tidak menyediakan image FreeBSD. Anda tidak dapat menyewa server FreeBSD pada platform ini, dan tidak ada bagian di bawah ini yang merupakan panduan instalasi untuk mesin yang dapat Anda beli di sini. Ini adalah perbandingan dua model isolasi, yang ditulis agar Anda dapat menentukan model yang benar-benar dibutuhkan oleh suatu workload dan membaca konfigurasi tim FreeBSD tanpa menerka-nerka.
Apa sebenarnya jail itu
Jail diperkenalkan di FreeBSD 4.0 pada Maret 2000. Dengan demikian, jail lebih lama daripada cgroups dan sekitar satu dekade lebih lama daripada Docker. Mekanisme ini menggunakan satu pemanggilan kernel. jail(8) menerima hierarki direktori dan menjalankan proses di dalamnya dengan ID jail yang terpasang. Kernel kemudian menolak sekumpulan operasi tertentu untuk setiap proses yang memiliki ID tersebut. Proses dalam jail tidak dapat melihat proses di luar jail-nya, tidak dapat memasang atau melepas filesystem, tidak dapat memuat modul kernel, dan tidak dapat melakukan bind ke alamat jaringan yang tidak diberikan kepada jail. Tidak ada jenis namespace terpisah yang perlu dipelajari dan tidak ada pengaktifan fitur satu per satu. Semua pembatasan diterapkan sebagai satu kesatuan dan disesuaikan melalui parameter dalam konfigurasi jail.
Pada host, jls menampilkan jail yang sedang berjalan. jexec web sh membuka shell di dalam jail bernama web.
Anda membuat jail dengan menempatkan userland FreeBSD ke dalam sebuah direktori. Base system dapat melakukan hal itu untuk Anda:
sudo bsdinstall jail /usr/local/jails/containers/webPerintah tersebut mengambil distribution set base untuk release Anda dan menjalankan langkah pascainstalasi biasa. Dengan demikian, Anda menetapkan password root dan memilih timezone seperti saat menyiapkan server baru. Hasilnya adalah instalasi FreeBSD yang berada di dalam sebuah folder. Selanjutnya, jelaskan konfigurasi jail tersebut dalam /etc/jail.conf:
web {
host.hostname = "web.example.internal";
path = "/usr/local/jails/containers/web";
ip4.addr = "10.0.0.10";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
}Jalankan jail tersebut, lalu periksa statusnya:
sudo service jail start web
jlsjls seharusnya sekarang menampilkan web beserta JID, hostname, dan alamat IP-nya. Jika jail tidak muncul, jalankan sudo jail -c web secara langsung. Perintah tersebut menerapkan konfigurasi yang sama di foreground dan mencetak parameter yang tidak dapat diterimanya, alih-alih membiarkan kegagalan hanya terlihat pada output service.
Baris yang perlu dibaca dua kali adalah exec.start = "/bin/sh /etc/rc". Menjalankan jail akan menjalankan boot script normal FreeBSD di dalamnya. Karena itu, jail menjalankan setiap service yang diaktifkan dalam /etc/rc.conf miliknya. Container Docker tidak memiliki langkah yang setara, karena container tersebut menjalankan proses entrypoint image dan berhenti ketika proses itu berhenti.
Cara memperoleh software: image dan registry dibandingkan dengan userland yang Anda isi sendiri
Inilah perbedaan yang langsung terasa sejak hari pertama.
Dengan Docker, Anda menyebutkan software lalu menerimanya. docker pull nginx mengambil image berlapis berbasis alamat konten yang dibuat dan diuji pihak lain, lalu docker compose up -d menjalankannya dengan volume dan jaringan yang terpasang. Registry adalah komponen utamanya. Sebagian besar nilai dalam alur kerja Docker berasal dari ribuan proyek yang menerbitkan image siap pakai. Karena itu, menjalankan Docker pada VPS menjadi pekerjaan singkat, bukan proyek.
FreeBSD tidak menyediakan registry publik default untuk image jail. Anda membuat userland kosong lalu menginstal software ke dalamnya, seperti saat menyiapkan server bare. Ini memerlukan lebih banyak pengetikan. Namun, prosesnya lebih transparan karena yang berjalan di dalam jail adalah software yang ditempatkan oleh pkg, dari kumpulan package yang sama dengan yang digunakan host.
Tooling membuat proses ini lebih singkat. BastilleBSD adalah jail manager yang umum digunakan dan tersedia sebagai package:
sudo pkg install bastille
sudo sysrc bastille_enable=YES
sudo bastille setup
sudo bastille bootstrap 15.1-RELEASEbastille setup mengonfigurasi jaringan, storage, dan firewall untuk Anda. bastille bootstrap mengunduh sebuah release satu kali, lalu setiap jail yang dibuat setelahnya menggunakan kembali release tersebut. FreeBSD 15.1 adalah production release saat ini dan dirilis pada June 2026; ganti dengan release yang Anda gunakan.
Setelah itu, pembuatan jail cukup dengan satu perintah, dan pengisiannya dengan satu perintah lagi:
sudo bastille create web 15.1-RELEASE 10.17.89.10/24
sudo bastille pkg web install nginx
sudo bastille service web nginx start
sudo bastille console webbastille console web memberi Anda login shell di dalam jail, sedangkan bastille list menampilkan apa saja yang tersedia pada host. Untuk mengulangi proses build, template Bastille menyimpan langkah-langkah dalam sebuah file lalu menerapkannya ke jail. Ini adalah padanan terdekat Dockerfile dalam ekosistem ini. Template dijalankan ulang pada setiap jail. Tidak ada yang datang dalam kondisi sudah ter-build.
Jadi, ringkasannya sederhana. Docker memberikan hasil build milik orang lain. Jail memberi Anda instalasi yang Anda buat sendiri. Jika software dalam daftar pilihan Anda hanya tersedia sebagai container image dan tidak dalam bentuk lain, pertanyaan ini sudah terjawab sebelum faktor lain dipertimbangkan.
Status dan upgrade: bagian yang diubah oleh ZFS
Docker sengaja memisahkan state. Filesystem container bersifat sementara, sedangkan data Anda berada dalam named volume atau bind mount. Proses upgrade adalah docker compose pull lalu docker compose up -d. Container diganti, dan semua data yang tidak Anda simpan dalam volume akan hilang. Ini menjadi fitur jika Anda mengikuti aturan tersebut, tetapi menjadi insiden kehilangan data jika Anda melupakannya. Karena itu, pilihan antara bind mount dan named volume sangat penting dalam stack Compose.
Jail tidak memisahkan state. ZFS membuat pendekatan ini dapat dilakukan. Seluruh jail merupakan satu dataset:
sudo zfs snapshot zroot/jails/containers/web@pre-upgrade
sudo pkg -j web upgrade
sudo zfs rollback zroot/jails/containers/web@pre-upgradePeriksa nama dataset yang sebenarnya dengan zfs list sebelum menjalankan perintah ini. Path di atas adalah layout yang digunakan handbook. Snapshot selesai dalam waktu sekitar satu detik dan hampir tidak menggunakan ruang hingga isi jail berubah. Jika upgrade menyebabkan service gagal, rollback mengembalikan seluruh userland ke kondisi sebelumnya, termasuk database paket dan file konfigurasi yang Anda edit secara manual pada pukul 2 pagi. Docker tidak memiliki padanan bawaan, karena modelnya mengasumsikan bahwa Anda tidak memerlukan fitur tersebut.
zfs clone adalah bagian lainnya. Clone dari snapshot merupakan jail baru yang dapat ditulis dan berbagi blok yang tidak berubah dengan parent-nya. Karena itu, membuat salinan staging dari jail berukuran 3 GB hampir tidak menggunakan ruang disk hingga Anda mulai mengubahnya. Dengan cara ini, administrator FreeBSD dapat membuat jail dengan kondisi "sama seperti production" untuk menguji upgrade.
Upgrade base system terpisah dari upgrade paket. Untuk jail yang memiliki salinan userland sendiri:
sudo freebsd-update -b /usr/local/jails/containers/web fetch installThin jail menghindari pekerjaan berulang tersebut. Thin jail memasang satu base bersama yang bersifat read-only melalui nullfs dan memberikan setiap jail writable layer kecil miliknya sendiri. Dengan demikian, Anda cukup melakukan patch pada base satu kali dan semua jail akan melihat hasilnya. Bastille membuat thin jail secara default.
Jaringan: port yang dipublikasikan vs keputusan pengalamatan
Docker menentukan jaringan untuk Anda dan meminta Anda memublikasikan pengecualiannya. Container ditempatkan pada bridge, saling terhubung berdasarkan nama service dalam jaringan yang ditentukan pengguna, dan -p 8080:80 mengekspos salah satunya ke host. Docker menulis aturan packet filter-nya sendiri agar mekanisme ini berjalan. Hal ini juga yang membuat port container yang dipublikasikan melewati ufw begitu saja.
Jail mengharuskan Anda memilih model sejak awal, dan ada dua model.
Shared IP. ip4.addr = "10.0.0.10" menambahkan alamat tersebut ke interface host yang sudah ada dan membatasi jail ke alamat itu. Jail tidak memiliki network stack sendiri, sehingga tidak dapat menjalankan firewall sendiri. Jail juga tidak benar-benar dapat bind ke setiap alamat: socket di dalam jail yang meminta 0.0.0.0 akan ditulis ulang oleh kernel menjadi alamat milik jail. Dua jail tidak dapat sama-sama listen pada port 80 di alamat yang sama. Karena itu, berikan satu alamat kepada masing-masing jail, atau tempatkan reverse proxy di depannya.
VNET. Tambahkan vnet; ke jail agar jail memperoleh network stack lengkap: interface sendiri, routing table sendiri, dan aturan firewall sendiri. Hubungkan jail ke host dengan epair, yaitu kabel virtual dengan satu ujung di setiap sisi, lalu tempatkan ujung pada sisi host ke sebuah bridge. Ini adalah padanan terdekat dengan jaringan yang diberikan Docker, dan merupakan mode yang digunakan oleh jenis jail Bastille -V dan -B.
Meneruskan port host ke jail adalah aturan redirect pf. Bastille membungkusnya:
sudo bastille rdr web tcp 80 80Tidak ada EXPOSE dan tidak ada publikasi otomatis. Tidak ada koneksi yang dapat mencapai jail kecuali alamatnya atau aturan redirect mengizinkannya. Proses awalnya lebih lambat, tetapi firewall menjadi jauh lebih tenang.
Batas resource: cgroups vs rctl
Docker membatasi container dengan cgroups, dan batas tersebut berada di tempat container didefinisikan: --memory=1g --cpus=1.5 pada command line, atau kunci yang sesuai dalam file Compose. Jika stack Anda sudah disimpan dalam file Docker Compose pada VPS, batas tersebut berada di samping service yang dikenainya dan ikut tersimpan bersamanya di git.
FreeBSD menggunakan rctl, yaitu subsistem yang harus diaktifkan. Pencatatan penggunaan resource dinonaktifkan secara default karena menambah sedikit overhead pada setiap alokasi. Tambahkan tunable tersebut ke /boot/loader.conf, lalu reboot:
kern.racct.enable=1Kemudian tetapkan aturan dan pantau penggunaannya:
sudo rctl -a jail:web:vmemoryuse:deny=1g
rctl -hu jail:webrctl -hu jail:web menampilkan penggunaan jail saat ini dalam satuan yang mudah dibaca, sehingga Anda dapat melihat seberapa dekat penggunaannya dengan batas sebelum terjadi kegagalan. Tindakan deny membuat alokasi yang melebihi batas gagal di dalam jail. Dengan demikian, Anda melihat error alokasi dari aplikasi itu sendiri, bukan pesan kill pada host.
Aturan yang ditambahkan dengan rctl -a akan hilang pada reboot berikutnya. Service FreeBSD rctl memuat ulang aturan dari /etc/rctl.conf. Karena itu, tulis aturan tersebut ke file itu dan aktifkan servicenya:
sudo sysrc rctl_enable=YESDi sinilah Docker jelas lebih praktis. Batas dalam file Compose ditinjau bersama service yang dibatasinya. Aturan rctl adalah satu baris dalam file terpisah yang menyebutkan jail yang didefinisikan di tempat lain.
Jika jawabannya adalah mesin virtual: bhyve
Jail menggunakan kernel host, sehingga beberapa hal tidak dapat dilakukan sama sekali. Jail tidak dapat menjalankan versi kernel yang berbeda, memuat modul kernel, atau menjalankan biner Linux seperti yang dilakukan container Linux. FreeBSD memiliki lapisan kompatibilitas Linux, yaitu linuxulator, tetapi lapisan ini hanya mengimplementasikan sebagian system call Linux dan bukan solusi umum untuk sembarang image Linux.
bhyve adalah hypervisor FreeBSD dan merupakan alat yang tepat jika Anda memerlukan batas isolasi mesin yang sebenarnya: sistem operasi yang berbeda, kernel yang berbeda, atau tenant yang tidak ingin Anda bagikan kernelnya. Konsekuensinya adalah penggunaan memori yang dicadangkan, bukan dibagikan, serta kernel kedua yang harus di-patch. Ini adalah keputusan yang sama seperti pada Linux saat memilih antara container dan mesin virtual penuh. Keputusan ini menentukan apakah Anda memerlukan VPS yang mendukung nested virtualization di bawahnya.
Ekosistem, yang merupakan alasan utama dan realistis sebagian besar tim menggunakan Docker
Semua penjelasan di atas membahas modelnya. Namun, bagi sebagian besar tim, keputusan ditentukan oleh besarnya ekosistem di sekitar masing-masing model.
Docker menyediakan Docker Hub dan GHCR, docker compose, Kubernetes saat satu mesin tidak lagi mencukupi, runner CI dengan dukungan container yang sudah terintegrasi, serta quickstart satu perintah pada README hampir setiap proyek. Jail menyediakan ports tree FreeBSD yang besar dan dikelola dengan cermat, serta kumpulan application bundle siap pakai yang jauh lebih sedikit. Jika sebuah proyek hanya menerbitkan container image tanpa format lain, pendekatan FreeBSD adalah membaca dokumentasinya lalu merakit sendiri semua komponennya.
Jail layak dipilih dalam kondisi sebaliknya. Gunakan jail jika Anda sudah menjalankan ZFS dan memerlukan snapshot serta rollback untuk seluruh service, jika service Anda native di FreeBSD, jika Anda menginginkan userland lengkap untuk setiap tenant alih-alih satu proses, atau jika Anda ingin kernel, packet filter, filesystem, dan dokumentasi dikelola bersama sebagai satu sistem. Poin terakhir inilah yang dimaksud ketika orang menyebut FreeBSD koheren. Penjelasan yang lebih luas tersedia dalam perbandingan Linux dan FreeBSD sebagai platform server dan dalam perubahan FreeBSD 15 untuk penggunaan server.
Satu penilaian penutup. Jika tim Anda sudah memahami Docker, biaya migrasi memang nyata dan manfaatnya harus spesifik. Jangan berpindah hanya demi kualitas isolasi; kedua model cukup mirip sehingga konfigurasi Anda lebih berpengaruh. Berpindahlah karena Anda menginginkan rollback seluruh service yang didukung ZFS, atau karena Anda sudah menggunakan FreeBSD.
FAQ
Dapatkah saya menjalankan image Docker di FreeBSD?
Tidak untuk image Linux, dan bukan sebagai metode yang didukung. FreeBSD memang mendukung container OCI: sudo pkg install -y podman-suite menginstal Podman, yang menjalankan container melalui ocijail, yaitu runtime yang membuat jail sungguhan di bawahnya. Runtime ini memerlukan fdescfs yang di-mount pada /dev/fd untuk memantau container, serta pf untuk NAT container (network address translation). Image OCI native FreeBSD memberikan hasil terbaik. Image Linux juga memerlukan lapisan kompatibilitas Linux, dan per Agustus 2026, port Podman FreeBSD masih disebut eksperimental. Jika deployment Anda berupa kumpulan image Linux, jalankan di Linux. Pada keluarga RHEL, berarti menginstal Docker di Rocky Linux atau AlmaLinux, tempat Podman kembali muncul sebagai paket yang sudah memiliki command docker sebelum Anda menginstal apa pun.
Apakah jail FreeBSD lebih aman daripada container Docker?
Keduanya menggunakan satu kernel host. Karena itu, bug pada kernel menjadi risiko bagi keduanya, dan tidak satu pun merupakan batas isolasi yang tepat untuk kode yang benar-benar tidak tepercaya. Perbedaannya terletak pada kondisi awal. Jail dimulai dengan serangkaian operasi yang secara umum ditolak, lalu Anda mengaktifkannya kembali satu parameter demi satu. Container Docker dimulai sebagai root di dalam sekumpulan namespace, dengan beberapa capability yang dinonaktifkan, dan penguatan tambahan harus diaktifkan secara eksplisit. Dalam praktiknya, konfigurasi lebih menentukan daripada modelnya: jail yang menjalankan allow.mount dan mengaktifkan allow.raw_sockets tidak lebih aman daripada container yang dikonfigurasi dengan cermat.
Bagaimana cara mencadangkan jail?
Buat snapshot dataset, lalu kirim snapshot tersebut. sudo zfs snapshot zroot/jails/containers/web@backup, kemudian zfs send snapshot itu ke pool lain atau ke dalam file yang Anda salin keluar dari server. Karena jail menyimpan seluruh userland-nya dalam satu dataset, snapshot mencakup paket yang terinstal dan data pada satu titik yang konsisten, termasuk setiap file konfigurasi yang Anda edit secara manual. Hal ini berlawanan dengan kebiasaan Docker, yaitu mencadangkan named volume dan file Compose, lalu membuat ulang bagian lainnya dari image.
Apakah saya memerlukan BastilleBSD, atau base system sudah cukup?
Base system sudah cukup, dan itu merupakan tempat yang lebih baik untuk memulai. jail.conf, jls, jexec, dan service jail start mencakup seluruh model tersebut. Setelah memahaminya, Anda dapat membaca konfigurasi host FreeBSD mana pun tanpa perlu mempelajari tooling host itu terlebih dahulu. Bastille adalah lapisan kemudahan di atasnya: Bastille melakukan bootstrap release, membuat thin jail, menerapkan template, dan menulis aturan redirect pf untuk Anda. Pelajari command dasar terlebih dahulu, lalu tambahkan Bastille ketika jumlah jail membuat pengetikan manual menjadi merepotkan.