Podman Quadlets: Ganti Docker Compose dengan systemd

Foto oleh Taylor Vick on Unsplash
Quadlet adalah file unit bergaya INI (.container, .network, .volume, .pod, dan lainnya) yang mendeskripsikan kontainer kepada systemd. podman-system-generator berjalan saat boot, memindai direktori Quadlet, dan menghasilkan unit .service asli dari setiap file. Anda mengelola kontainer dengan perintah systemctl biasa, bukan CLI khusus kontainer.
Unit rootless pengguna diletakkan di folder containers/systemd di bawah XDG_CONFIG_HOME, sedangkan unit rootful sistem-wide di /etc/containers/systemd/. Generator hanya memindai sekumpulan search path tetap, jadi unit di direktori yang salah diabaikan tanpa peringatan. Setelah menambahkan file, jalankan systemctl daemon-reload agar generator membacanya.
Untuk server self-hosted, bisa. Quadlet memberi kontainer rootless, auto-restart, urutan boot, log journald, dan auto-update bawaan tanpa daemon Docker. Komprominya adalah tidak ada satu perintah up yang membaca seluruh proyek, jadi aplikasi multi-kontainer menjadi beberapa file unit alih-alih satu dokumen docker-compose.yml.
Setel AutoUpdate ke registry di seksi Container. Timer podman-auto-update.timer berjalan setiap hari tengah malam, memeriksa registry untuk image lebih baru, menariknya, lalu me-restart unit. Ini membutuhkan referensi image yang fully qualified. Jika unit gagal restart setelah pembaruan, Podman otomatis rollback ke image sebelumnya.
Service systemd rootless terikat pada sesi pengguna dan berhenti saat Anda logout kecuali lingering diaktifkan. Jalankan loginctl enable-linger untuk akun tersebut agar kontainer tetap berjalan setelah sesi SSH ditutup dan menyala lagi setelah reboot. Dikombinasikan dengan WantedBy diset ke default.target, kontainer berperilaku seperti service sistem biasa.

Foto oleh Taylor Vick on Unsplash
Ringkasan Utama
Podman Quadlets memungkinkan Anda mendeskripsikan kontainer sebagai unit systemd asli. Anda menulis file .container biasa, lalu podman-system-generator mengubahnya menjadi service yang dikelola langsung oleh systemd. Hasilnya kontainer rootless, auto-restart, urutan boot, log journald, dan auto-update registry bawaan tanpa daemon Docker atau tool Compose terpisah.
Saya menjalankan server pribadi dengan Docker Compose selama bertahun-tahun. Itu berfungsi, tetapi selalu terasa seperti init system kedua yang ditempelkan di atas yang pertama: daemon Docker berjalan sebagai root, kontainer restart karena sebuah string policy menyuruh daemon, dan log tersimpan dalam file JSON yang hanya bisa dibaca oleh CLI docker. Saat mesin reboot, systemd menjalankan daemon Docker, lalu daemon menjalankan kontainer saya. Dua supervisor untuk satu pekerjaan.
Podman Quadlets meruntuhkan tumpukan itu. Alih-alih docker-compose.yml yang ditafsirkan oleh daemon yang berjalan terus-menerus, Anda menulis file unit deklaratif yang dimengerti langsung oleh systemd. Tidak ada daemon, kontainer bisa berjalan sepenuhnya rootless, dan setiap fitur yang sudah dimiliki systemd untuk service biasa juga berlaku untuk kontainer. Beginilah cara saya menjalankan semuanya di VPS sekarang, dan saya tidak pernah merindukan Compose sekali pun.
Quadlet adalah file kecil bergaya INI yang mendeskripsikan kontainer sebagaimana unit systemd mendeskripsikan sebuah service. Podman menyertakan generator bernama podman-system-generator yang berjalan di awal urutan boot, memindai sekumpulan direktori, dan menerjemahkan setiap Quadlet menjadi unit .service asli secara otomatis. Anda tidak pernah menulis file service yang rumit dengan tangan, dan tidak pernah menyimpan file hasil generate ke disk — generator membuatnya ulang setiap kali daemon-reload.
Quadlet menangani lebih dari sekadar kontainer tunggal. Selain file .container ada file .network, .volume, dan .pod untuk network, named volume, dan pod yang dibutuhkan aplikasi Anda, ditambah .kube, .image, .build, dan .artifact untuk kasus yang lebih lanjut. Karena rilis Podman yang lebih baru menyertakan generator yang lebih baik, service Anda diam-diam menerima perbaikannya saat daemon-reload berikutnya berjalan — deskripsi tetap sama sementara mekanisme di baliknya menjadi lebih baik.
Berikut Quadlet yang berfungsi untuk blog Ghost, ditaruh di direktori pengguna rootless. Bentuknya hampir seperti bagian environment sebuah file Compose, tetapi setiap seksinya memetakan langsung ke konsep systemd yang mungkin sudah Anda kenal: Unit untuk urutan dan dependensi, Container untuk opsi khusus Podman, Service untuk restart policy, dan Install untuk apa yang mengaktifkan unit saat boot.
# ~/.config/containers/systemd/ghost.container
[Unit]
Description=Ghost blog
After=network-online.target
Wants=network-online.target
[Container]
Image=docker.io/library/ghost:5-alpine
AutoUpdate=registry
PublishPort=2368:2368
Volume=ghost-content.volume:/var/lib/ghost/content
Environment=NODE_ENV=production
Environment=url=https://blog.example.com
[Service]
Restart=always
TimeoutStartSec=900
[Install]
WantedBy=default.targetSimpan file itu, lalu biarkan systemd menemukannya. Sebuah daemon-reload memicu generator, dan setelah itu kontainer menjadi service biasa yang Anda start, stop, enable, dan periksa dengan perintah yang sama seperti apa pun yang dijalankan systemd. Nama service adalah nama file dengan ekstensi diganti, jadi ghost.container menjadi ghost.service.
# register the generated service, then start it
systemctl --user daemon-reload
systemctl --user start ghost.service
journalctl --user -u ghost.service -fQuadlet rootless untuk seorang pengguna diletakkan di direktori yang ada di bagian atas sampel, yang memetakan ke XDG_CONFIG_HOME di dalam containers dan systemd. Unit rootful sistem-wide berada di bawah etc, containers, systemd. Letakkan file di tempat yang benar lebih dulu — generator hanya memindai sekumpulan search path tetap, jadi unit di direktori yang salah akan diabaikan tanpa peringatan.
Alasan terbesar saya berpindah adalah rootless. Sebuah Quadlet di direktori pengguna Anda berjalan sebagai pengguna tanpa hak istimewa, tanpa daemon dan tanpa root, sehingga sebuah container breakout mendarat di dalam akun pengguna biasa alih-alih di host sebagai root. Semua hal lain mengikuti karena kontainer menjadi unit systemd kelas satu, bukan proses yang dikelola daemon.
Karena kontainer adalah unit sungguhan, tool yang sudah Anda percaya langsung bekerja, dan tidak ada hal khusus kontainer yang perlu dipelajari:
Service rootless berhenti saat pengguna logout kecuali lingering diaktifkan. Jalankan loginctl enable-linger untuk akun tersebut, atau kontainer Anda akan mati begitu sesi SSH ditutup dan tidak akan pernah bertahan melewati reboot. Ini satu jebakan yang menjerat semua orang yang memindahkan beban kerja self-hosted ke Podman rootless — aktifkan linger sebelum Anda mengandalkannya.
Setel AutoUpdate=registry di seksi Container, seperti pada sampel, dan Podman bisa memperbarui kontainer untuk Anda. Timer podman-auto-update.timer berjalan setiap hari tengah malam, memeriksa registry untuk image lebih baru di balik setiap label auto-update, menariknya, lalu me-restart unit. Ini hanya berfungsi dengan referensi image yang fully qualified, karena Podman butuh nama pasti untuk memeriksa ulang — sebuah tag polos atau image ID tidak memberinya pembanding.
Jaring pengamannya adalah rollback. Jika unit gagal restart dengan bersih setelah pembaruan, Podman kembali ke image sebelumnya dan me-restart service lagi, sehingga rilis buruk tidak meninggalkan Anda dengan kontainer mati di tengah malam. Ada juga AutoUpdate=local untuk image yang Anda build sendiri di host, di mana Podman membandingkan kontainer dengan penyimpanan image lokal Anda alih-alih registry jarak jauh.
Compose dan Quadlet memecahkan masalah yang tumpang tindih, tetapi keduanya berada di lapisan berbeda. Compose adalah tool yang berbicara ke daemon; Quadlet adalah deskripsi yang dikonsumsi langsung oleh systemd. Tabel ini adalah perbandingan yang saya harap saya miliki saat memulai migrasi.
| Aspek | Docker Compose | Podman Quadlet |
|---|---|---|
| Model proses | Daemon Docker berjalan terus, biasanya root | Tanpa daemon; rootless, dijalankan langsung systemd |
| Format definisi | Satu docker-compose.yml dalam YAML | File unit .container, .network, .volume terpisah |
| Pengelola siklus hidup | CLI compose membungkus daemon | systemd mengelola service hasil generate secara asli |
| Restart saat boot | restart policy plus daemon yang harus mulai dulu | WantedBy=default.target plus lingering pengguna |
| Log | docker logs membaca file JSON per kontainer | journald, dikueri dengan journalctl seperti service lain |
| Auto-update | Tool eksternal seperti Watchtower | AutoUpdate=registry bawaan plus timer harian |
| Urutan dependensi | depends_on di dalam file compose | After= dan Requires= dari systemd |
Quadlet bukan pengganti langsung untuk setiap alur kerja Compose — tidak ada satu perintah up yang membaca seluruh proyek, dan aplikasi multi-kontainer menjadi beberapa file unit alih-alih satu dokumen. Tetapi untuk server self-hosted yang seharusnya boot, restart, log, dan update seperti bagian sistem operasi lainnya, menjalankan kontainer sebagai unit systemd adalah model yang lebih bersih. Mulailah dengan memindahkan satu service, buktikan jalur reboot dan auto-update, lalu pindahkan sisanya.