Instal Docker di Rocky Linux atau AlmaLinux
Pelajari instalasi Docker Engine dengan dnf, termasuk konflik Podman pada perintah docker, label SELinux untuk bind mount, dan port Firewalld yang tetap terbuka.
Instal Docker di Rocky Linux dan AlmaLinux
Untuk menginstal Docker di Rocky Linux atau AlmaLinux, tambahkan repositori dnf milik Docker, instal engine beserta plugin compose, lalu aktifkan servicenya. Bagian ini terdiri dari empat perintah dan sama pada kedua distribusi karena keduanya merupakan rebuild dari Red Hat Enterprise Linux (RHEL) serta menggunakan tata letak paket yang sama. CentOS Stream bekerja dengan cara yang sama.
Proses instalasinya singkat, sehingga sebagian besar panduan ini membahas perbedaan Enterprise Linux (EL) dari Ubuntu. Podman mungkin sudah menggunakan perintah docker pada image Anda. SELinux memblokir file yang di-bind mount sampai file tersebut memiliki label yang benar. Firewalld tidak memfilter port yang dipublikasikan Docker, sehingga port container dapat terbuka ke Internet meskipun firewall-cmd melaporkan tidak ada port yang terbuka.
Jangan gunakan convenience script Docker dari get.docker.com. Dokumentasi Docker sendiri menyatakan bahwa script tersebut tidak direkomendasikan untuk production. Script itu menulis ulang konfigurasi repositori tanpa meminta konfirmasi dan tidak dapat dijalankan ulang dengan aman untuk melakukan upgrade. Menambahkan repositori secara manual membuat dnf upgrade memperlakukan Docker seperti paket lainnya pada server.
Apakah podman sudah menangani perintah docker?
Rocky Linux dan AlmaLinux menyediakan podman di repositori default-nya, dan banyak image VPS memasangnya secara otomatis. Beberapa image bahkan memasang podman-docker, yang menempatkan skrip shell di /usr/bin/docker untuk memanggil podman. Setiap perintah docker yang Anda ketik kemudian menjalankan podman, sehingga panduan yang ditulis untuk Docker mulai menghasilkan output yang tidak Anda harapkan.
Petunjuk pertama adalah banner. Skrip /usr/bin/docker memeriksa file /etc/containers/nodocker. Jika file tersebut tidak ada, skrip menampilkan satu baris sebelum menjalankan apa pun:
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.Seseorang mungkin telah membuat file tersebut untuk menyembunyikan banner. Jadi, jangan hanya mengandalkannya. Tanyakan database paket untuk mengetahui paket yang memiliki binary tersebut:
command -v docker
rpm -qf "$(command -v docker)"Jawaban yang diawali podman-docker berarti podman yang menangani perintah tersebut. Jawaban yang diawali docker-ce-cli berarti Docker yang sebenarnya. Jika rpm -qf melaporkan bahwa tidak ada paket yang memiliki file tersebut, seseorang memasangnya secara manual. Baca skripnya sebelum mempercayainya.
Podman menjalankan image OCI yang sama dan merupakan pilihan yang wajar. Jika Anda ingin menggunakannya, Anda dapat berhenti di sini. Jika Anda ingin menggunakan Docker Engine, hapus paket yang berkonflik terlebih dahulu. Berikut adalah daftar yang didokumentasikan Docker untuk RHEL:
sudo dnf remove docker docker-client docker-client-latest docker-common \
docker-latest docker-latest-logrotate docker-logrotate docker-engine podman runcBaca paket yang akan dihapus oleh dnf sebelum mengonfirmasi. Pada image VPS baru, daftarnya biasanya singkat. Pada server yang sudah digunakan, penghapusan podman dapat menghapus cockpit-podman atau alat lain yang bergantung padanya.
Secara prinsip, podman dapat dipertahankan bersama Docker: hapus hanya podman-docker agar nama docker tersedia, serta runc, yang digantikan oleh paket containerd.io. Dokumentasi Docker menganggap podman sebagai paket yang berkonflik. Jadi, tata letak ini tidak didukung oleh Docker. Jika instalasi masih melaporkan konflik, gunakan daftar penghapusan lengkap di atas.
Tambahkan repositori Docker dengan dnf config-manager
Docker menyediakan paket RPM untuk Enterprise Linux di download.docker.com. File repositori tersebut mengarah ke tree CentOS, yang digunakan Rocky Linux dan AlmaLinux. Diperiksa pada Agustus 2026, Docker mendokumentasikan repositori ini untuk CentOS Stream 9 dan CentOS Stream 10.
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repodnf versi 5 menghapus argumen --add-repo, sehingga perintah kedua gagal pada rilis yang lebih baru. Periksa versi yang Anda gunakan, lalu pilih format yang sesuai:
dnf --versionJika hasilnya menunjukkan versi 5.x, gunakan format subperintah:
sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/centos/docker-ce.repoKeduanya menulis file yang sama ke /etc/yum.repos.d/docker-ce.repo. Format yang salah gagal dengan error argumen tidak dikenal, bukan melakukan kesalahan secara diam-diam. Dengan demikian, Anda akan langsung mengetahuinya.
File repositori tersebut menetapkan baseurl ke path yang berisi $releasever, lalu dnf memperluas variabel tersebut berdasarkan paket rilis Anda. Rocky Linux dan AlmaLinux menetapkannya ke nomor versi mayor. Jadi, nilainya adalah 9 pada EL 9 dan 10 pada EL 10. Itulah sebabnya repositori CentOS dapat digunakan dengan benar pada sistem Rocky. Konfirmasikan hasil perluasan tersebut sebelum menginstal:
sudo dnf repoinfo docker-ce-stableBaca baris Repo-baseurl. Baris tersebut harus diakhiri dengan /9/x86_64/stable atau /10/x86_64/stable. Jika rilis Anda menetapkan $releasever ke versi titik seperti 9.6, dnf melaporkan Status code: 404 untuk URL tersebut saat mengambil metadata. Perbaiki dengan mengedit /etc/yum.repos.d/docker-ce.repo dan mengganti $releasever dengan nomor versi mayor tanpa tambahan apa pun.
Instal engine dan plugin compose
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginLima paket ini memiliki fungsi masing-masing. docker-ce adalah daemon, yaitu dockerd. docker-ce-cli adalah perintah docker yang Anda ketik. containerd.io adalah runtime container yang dikendalikan daemon. docker-buildx-plugin digunakan untuk membangun image. docker-compose-plugin menyediakan docker compose sebagai subperintah.
Paket-paket ini tidak menginstal biner docker-compose yang menggunakan tanda hubung. Biner tersebut merupakan Compose v1, yang masa dukungnya berakhir pada Juli 2023. Semua konfigurasi yang memanggil docker-compose dengan tanda hubung harus diperbarui agar memanggil docker compose dengan spasi.
Proses instalasi pertama berhenti untuk mengimpor kunci penandatanganan Docker dan menampilkan sidik jarinya. Kunci tersebut berasal dari gpgkey=https://download.docker.com/linux/centos/gpg dalam file repo yang baru saja Anda tambahkan. Karena itu, bandingkan sidik jari yang ditampilkan dnf dengan URL tersebut sebelum menerimanya.
Ada satu kegagalan yang cukup sering terjadi sehingga perlu disebutkan. Jika dnf melaporkan bahwa containerd.io memerlukan container-selinux dan tidak ada paket yang menyediakannya, repositori AppStream dinonaktifkan. Jalankan dnf repolist dan pastikan appstream tercantum, karena di situlah container-selinux dirilis pada EL 9 dan EL 10.
Mulai Docker dan pastikan Docker berjalan
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker run --rm hello-worldPaket RPM Docker membiarkan daemon dalam keadaan berhenti dan dinonaktifkan setelah instalasi. Karena itu, langkah ini tercantum di halaman Docker untuk CentOS, tetapi tidak di halaman Ubuntu, karena paket deb pada Ubuntu memulai service secara otomatis. Jika enable dilewati, Docker akan berjalan sampai reboot berikutnya. Setelah itu, Docker tetap berhenti dan semua container ikut berhenti.
systemctl status harus menampilkan Active: active (running). Container hello-world harus mencetak This message shows that your installation appears to be working correctly. lalu berhenti. Jika yang ditampilkan justru error izin pada /var/run/docker.sock, berarti sudo tidak disertakan. Bagian tentang grup docker di bawah ini akan memperbaikinya.
Periksa plugin Compose secara terpisah karena plugin ini merupakan paket yang berbeda. Plugin dapat tidak terpasang meskipun engine berjalan:
docker compose versionHasil yang benar terlihat seperti Docker Compose version v2.x.x. Menjalankan kembali service setelah reboot merupakan hal yang berbeda dari mengaktifkan daemon. kebijakan restart menentukan apakah service Compose berjalan kembali saat boot.
Mengapa bind mount menghasilkan permission denied?
Rocky Linux dan AlmaLinux menjalankan SELinux (Security-Enhanced Linux) dalam mode enforcing secara default. Konfirmasikan dengan getenforce, yang mencetak Enforcing.
Container Docker berjalan dengan tipe SELinux container_t, dan tipe tersebut hanya dapat membaca serta menulis file yang diberi label container_file_t. Direktori yang Anda buat pada host membawa label dari path induknya, dan label tersebut bukan container_file_t. Container ditolak meskipun owner, group, dan mode terlihat benar dari sisi host. Reproduksi masalah ini dengan tiga perintah:
sudo mkdir -p /srv/site
echo hello | sudo tee /srv/site/index.html
sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro nginx:alpine cat /usr/share/nginx/html/index.htmlContainer mencetak:
cat: can't open '/usr/share/nginx/html/index.html': Permission deniedDua perintah menunjukkan penyebabnya. ls -ldZ /srv/site mencetak label, yang untuk path di bawah /srv adalah system_u:object_r:var_t:s0, bukan container_file_t. Kemudian sudo ausearch -m avc -ts recent mencetak catatan audit kernel yang berisi avc: denied { read }, yaitu field scontext= yang menyebut container_t, serta field tcontext= yang menyebut label yang baru saja Anda lihat pada direktori. Ketidaksesuaian antara kedua field tersebut adalah seluruh penyebabnya.
Perbaikannya adalah menambahkan suffix pada argumen volume. Docker akan memberi label baru pada path tersebut:
sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro,z nginx:alpine cat /usr/share/nginx/html/index.html:z dalam huruf kecil memberi label pada konten sebagai shared, sehingga beberapa container dapat menggunakan direktori yang sama. :Z dalam huruf besar memberi label sebagai private dan unshared, yang mengikatnya ke satu container. Container kedua yang membaca path yang sama akan ditolak. Gunakan :z untuk apa pun yang juga diakses oleh sidecar atau container backup. Gunakan :Z untuk direktori database yang dimiliki satu container.
Dokumentasi Docker memuat peringatan yang perlu diulangi karena pelabelan ulang ini bersifat rekursif. Bind-mount direktori sistem seperti /home atau /usr dengan :Z "membuat host Anda tidak dapat dioperasikan dan Anda mungkin perlu memberi label ulang pada file host secara manual". Arahkan suffix ini hanya ke direktori yang Anda buat untuk container, bukan ke path sistem.
Dalam Compose, suffix diletakkan pada string yang sama:
services:
web:
image: nginx:alpine
volumes:
- /srv/site:/usr/share/nginx/html:ro,zAda dua batasan yang mudah terlewat. Flag --mount sama sekali tidak dapat menetapkan label SELinux, jadi gunakan -v jika Anda memerlukannya. Named volume tidak memerlukan suffix karena Docker memberi label pada direktori yang dibuatnya di bawah /var/lib/docker/volumes secara otomatis.
Jangan menonaktifkan SELinux. Gunakan sudo setenforce 0 hanya sebagai pengujian selama satu menit. Jika container kemudian berjalan, masalahnya adalah label dan :z adalah jawabannya. Segera aktifkan kembali dengan sudo setenforce 1. Pada Enterprise Linux, permission denied pada bind mount memiliki dua penyebab terpisah yang terlihat sama dari dalam container. Salah satunya adalah label SELinux. Penyebab lainnya adalah ownership user dan group numerik biasa, yang diselesaikan oleh variabel PUID dan PGID. ls -lnZ menampilkan mode, owner numerik, dan label dalam satu baris, sehingga Anda dapat mengetahui masalah mana yang sedang dihadapi.
Mengapa port yang dipublikasikan dapat diakses ketika firewalld terlihat tertutup?
Firewalld adalah firewall default pada Rocky Linux dan AlmaLinux. Periksa apakah firewall sedang berjalan dengan sudo systemctl is-active firewalld. Sekarang publikasikan sebuah port dan lihat port yang dianggap terbuka oleh firewalld:
sudo docker run -d --name web -p 8080:80 nginx:alpine
sudo firewall-cmd --list-portsfirewall-cmd mencetak baris kosong. Dari mesin lain, curl -I http://YOUR_SERVER_IP:8080/ mengembalikan HTTP/1.1 200 OK. Port tersebut terbuka ke Internet, tetapi firewall Anda tidak melaporkannya.
Penyebabnya adalah jalur yang dilalui paket. Aturan zona firewalld memfilter trafik yang ditujukan langsung ke host. Port yang dipublikasikan tidak ditujukan ke host. Docker memasang aturan destination NAT (network address translation) yang mengubah tujuan menjadi alamat container sebelum paket mencapai jalur input host. Karena itu, kernel meneruskan paket tersebut, bukan mengirimkannya ke host secara lokal. Docker kemudian menempatkan interface bridge-nya dalam zona firewalld bernama docker dengan target ACCEPT, lalu menambahkan kebijakan forwarding bernama docker-forwarding yang mengizinkan forwarding dari zona mana pun ke zona docker. Aturan zona Anda tidak pernah memproses paket tersebut.
Perbaikan paling bersih tidak memerlukan aturan firewall. Ikat sisi host dari publikasi port ke loopback, lalu tempatkan reverse proxy di depannya:
sudo docker rm -f web
sudo docker run -d --name web -p 127.0.0.1:8080:80 nginx:alpine
curl -I http://127.0.0.1:8080/curl lokal mengembalikan HTTP/1.1 200 OK, sedangkan permintaan yang sama dari mesin lain tidak lagi dapat terhubung. Jika argumen -p tidak berisi alamat host, port tersebut dipublikasikan pada setiap interface. Karena itu, anggap -p 8080:80 tanpa alamat sebagai keputusan untuk mengekspos service tersebut secara publik.
Jika Anda memerlukan service yang dapat diakses dari alamat tertentu tetapi tidak dari alamat lain, Docker menyediakan chain khusus. DOCKER-USER diproses sebelum aturan accept milik Docker sendiri. Karena itu, aturan yang Anda tambahkan di sana tetap ada setelah Docker me-restart dan menulis ulang chain-nya:
sudo iptables -I DOCKER-USER -i enp1s0 ! -s 203.0.113.10 -j DROP
sudo iptables -S DOCKER-USERAmbil nama interface dari ip route show default, bukan dengan mengasumsikan eth0, karena EL image saat ini menggunakan nama seperti enp1s0 atau ens3. Pada Rocky dan AlmaLinux, perintah iptables adalah lapisan kompatibilitas di atas nftables, dan chain Docker dapat dilihat melalui perintah tersebut. Aturan yang ditambahkan dengan cara ini akan hilang setelah reboot jika tidak disimpan. Setelah aturan sesuai, tuliskan aturan tersebut ke dalam unit systemd.
Docker Engine 28.0, yang dirilis pada 2025, menutup celah terkait: akses routed langsung ke port container yang tidak pernah dipublikasikan kini diblokir dalam chain DOCKER. Perubahan tersebut tidak memengaruhi port yang dipublikasikan. Karena itu, semua langkah di atas tetap berlaku pada versi saat ini. Bentuk kebiasaan operasional berikut: setelah setiap sudo firewall-cmd --reload, uji kembali port yang dipublikasikan. Jika port tersebut berhenti merespons, sudo systemctl restart docker memasang ulang aturan Docker.
Administrator Ubuntu menghadapi masalah yang sama melalui tool berbeda, yaitu mengapa port Docker yang dipublikasikan mengabaikan aturan ufw. Pada kedua kasus, penyebabnya adalah jalur NAT. Yang berubah hanya firewall yang berada di depannya.
Tambahkan pengguna non-root ke grup docker
Mengetik sudo sebelum setiap perintah docker akan merepotkan, dan grup docker menghilangkan kebutuhan itu:
sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-worldusermod -aG mengedit /etc/group, tetapi shell saat ini sudah memiliki daftar grupnya sendiri. Karena itu, perubahan tersebut belum berlaku sampai Anda mendapatkan shell baru. newgrp docker memulai shell dengan grup tersebut agar Anda dapat langsung mengujinya. Sesi SSH baru akan menerapkan perubahan ini secara otomatis.
Pahami dengan jelas hak akses yang diberikan grup tersebut. Keanggotaan memberikan akses tulis ke /var/run/docker.sock. Apa pun yang dapat berkomunikasi dengan socket tersebut dapat meminta daemon memulai container yang memasang filesystem host. Satu perintah menunjukkan dampaknya:
docker run --rm -v /:/host alpine wc -l /host/etc/shadowPerintah tersebut membaca file yang hanya dapat dibaca oleh root, dari akun yang tidak memiliki hak sudo. Dokumentasi pascainstalasi Docker juga menyatakan hal yang sama: grup docker memberikan hak akses yang setara dengan root. Tambahkan akun ke grup ini hanya jika Anda juga akan memberikan akun tersebut sudo. Jika Anda sedang menyiapkan akun pada server baru, tentukan hal ini bersama pengaturan pengguna dengan hak minimum pada VPS lainnya, bukan setelah semuanya selesai.
Docker juga menyediakan mode rootless yang menjalankan daemon sebagai pengguna tanpa hak istimewa. Mode ini menggunakan jalur instalasi terpisah dan mengubah perilaku driver penyimpanan serta port di bawah 1024. Karena itu, rencanakan mode ini sebagai proyek tersendiri, bukan sebagai flag yang ditambahkan kemudian.
Langkah berikutnya
Kini Anda memiliki engine, plugin compose, service yang tetap berjalan setelah reboot, serta tiga perilaku khusus EL yang didokumentasikan di atas. Langkah berikutnya adalah compose.yaml per service. Anatomi file Compose membahas format file dan perintah yang mengelolanya. Jika ini adalah host container pertama Anda, Menjalankan Docker pada VPS membahas pertanyaan tentang penentuan ukuran, penyimpanan, dan kebersihan image yang tidak dibahas dalam panduan ini.
FAQ
Apakah repositori CentOS milik Docker berfungsi pada Rocky Linux dan AlmaLinux?
Ya. Tambahkan https://download.docker.com/linux/centos/docker-ce.repo dengan dnf config-manager. baseurl dalam file tersebut berisi $releasever, dan Rocky Linux serta AlmaLinux mengembangkannya menjadi nomor versi mayor. Jadi, sistem EL 9 menggunakan pohon CentOS 9, sedangkan sistem EL 10 menggunakan pohon CentOS 10. Konfirmasikan ekspansinya dengan sudo dnf repoinfo docker-ce-stable, lalu baca baris Repo-baseurl. Status code: 404 saat dnf mengambil metadata berarti variabel tersebut diekspansi menjadi point release. Ubah /etc/yum.repos.d/docker-ce.repo agar menggunakan nomor versi mayor tanpa tambahan untuk memperbaikinya.
Apakah Docker dan podman dapat diinstal pada server yang sama?
Dokumentasi Docker mencantumkan podman dan runc sebagai paket yang konflik, serta meminta Anda menghapus keduanya sebelum menginstal Docker Engine. Konflik konkretnya adalah paket podman-docker, yang memiliki /usr/bin/docker dan mengubah setiap perintah docker menjadi perintah podman. Jalankan rpm -qf "$(command -v docker)" untuk melihat paket yang memiliki path tersebut. Jika output diawali podman-docker, podman yang merespons. Docker tidak mendukung penggunaan kedua engine dalam satu tata letak. Jadi, pada server penting, pilih salah satunya.
Mengapa container saya mendapatkan kesalahan permission denied pada bind mount?
SELinux secara default berada dalam mode enforcing pada Rocky Linux dan AlmaLinux. Container berjalan sebagai tipe container_t dan hanya dapat mengakses file yang diberi label container_file_t. Karena itu, direktori yang Anda buat memiliki label yang salah dan akses ditolak, terlepas dari owner dan modenya. Konfirmasikan dengan ls -ldZ pada path host dan sudo ausearch -m avc -ts recent, yang mencetak avc: denied bersama dua konteks yang tidak cocok. Tambahkan :z ke argumen volume untuk konten yang dibagikan antar-container, atau :Z untuk konten yang hanya digunakan satu container. Jangan pernah mengarahkan :Z ke /home atau /usr, karena pelabelan ulang bersifat rekursif dan akan merusak host.
Apakah saya perlu membuka port di firewalld untuk memublikasikan port container?
Tidak, dan itulah masalahnya. Aturan NAT Docker mengubah alamat tujuan sebelum paket mencapai jalur input host. Karena itu, aturan zona firewalld tidak pernah memeriksanya. Docker juga menempatkan bridge-nya dalam zona firewalld bernama docker dengan target ACCEPT. Container yang dijalankan dengan -p 8080:80 dapat diakses dari Internet, sedangkan sudo firewall-cmd --list-ports tidak mencetak apa pun. Publikasikan ke alamat tertentu dengan -p 127.0.0.1:8080:80 jika hanya host yang boleh mengakses service tersebut, atau masukkan aturan pemfilteran ke chain DOCKER-USER, yang diproses Docker sebelum aturan accept miliknya sendiri.
Apakah menambahkan user saya ke grup docker aman?
Tindakan tersebut memberikan hak root. Anggota grup docker dapat menulis ke /var/run/docker.sock, lalu docker run --rm -v /:/host alpine wc -l /host/etc/shadow dapat membaca file yang hanya dapat diakses root dari akun tanpa hak sudo. Dokumentasi Docker setelah instalasi menyatakan ekuivalensi yang sama. Tambahkan hanya akun yang sejak awal Anda percayai untuk menggunakan sudo, dan tetap gunakan sudo docker untuk akun bersama atau akun service. Mode rootless adalah alternatif jika Anda memerlukan container di bawah user tanpa hak istimewa. Mode ini menggunakan jalur instalasi terpisah, bukan sebuah pengaturan.