SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-13

Cara Pasang Docker di Rocky Linux dan AlmaLinux

Ketahui cara pasang Docker Engine di Rocky Linux dan AlmaLinux menggunakan dnf. Panduan ini menyelesaikan konflik Podman serta isu kebenaran SELinux pada bind mounts.

Memasang Docker pada Rocky Linux dan AlmaLinux

Untuk memasang Docker pada Rocky Linux atau AlmaLinux, anda perlu menambah repositori dnf milik Docker, memasang enjin tersebut bersama pemalam compose, kemudian mendayakan servisnya. Bahagian ini melibatkan empat arahan, dan ia adalah sama pada kedua-dua pengedaran kerana kedua-duanya merupakan binaan semula Red Hat Enterprise Linux (RHEL) serta berkongsi susun atur pakej yang sama. CentOS Stream berfungsi dengan cara yang sama.

Proses pemasangan ini singkat, jadi sebahagian besar panduan ini merangkumi perbezaan antara Enterprise Linux (EL) dengan Ubuntu. Podman mungkin sudah menggunakan arahan docker pada imej anda. SELinux menyekat fail yang dipasang secara bind-mount sehingga ia mempunyai label yang betul. Firewalld tidak menapis port yang diterbitkan oleh Docker, jadi port kontena boleh terdedah kepada internet walaupun firewall-cmd melaporkan tiada apa-apa yang terbuka.

Jangan gunakan skrip kemudahan Docker daripada get.docker.com. Dokumentasi Docker sendiri menyatakan bahawa ia tidak disyorkan untuk persekitaran pengeluaran (production). Skrip tersebut menulis semula konfigurasi repositori anda tanpa bertanya, dan ia tidak boleh dijalankan semula dengan selamat untuk tujuan naik taraf. Menambah repositori secara manual bermakna dnf upgrade melayan Docker seperti pakej lain pada sistem anda.

Adakah podman sudah menjawab arahan docker?

Rocky Linux dan AlmaLinux menyertakan podman dalam repositori lalai mereka, dan banyak imej VPS memasangnya untuk anda. Sesetengah imej melangkah lebih jauh dengan memasang podman-docker, yang meletakkan skrip shell pada /usr/bin/docker untuk memanggil podman. Setiap arahan docker yang anda taip kemudiannya akan menjalankan podman, jadi panduan yang ditulis untuk Docker mula menghasilkan output yang tidak anda jangkakan.

Petunjuk pertama ialah sepanduk. Skrip /usr/bin/docker menyemak fail /etc/containers/nodocker, dan apabila fail itu tiada, ia mencetak satu baris sebelum menjalankan apa-apa:

Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.

Seseorang mungkin telah mencipta fail tersebut untuk menyenyapkan sepanduk itu, jadi jangan bergantung padanya semata-mata. Tanya pangkalan data pakej pakej mana yang memiliki binari tersebut:

command -v docker
rpm -qf "$(command -v docker)"

Jawapan yang bermula dengan podman-docker bermakna podman sedang menjawab. Jawapan yang bermula dengan docker-ce-cli bermakna Docker yang sebenar. Jika rpm -qf melaporkan bahawa tiada pakej yang memiliki fail tersebut, seseorang telah memasangnya secara manual dan anda harus membaca skrip tersebut sebelum mempercayainya.

Podman menjalankan imej OCI yang sama dan merupakan pilihan yang munasabah. Jika anda mahukannya, berhenti di sini. Jika anda mahukan Docker Engine, buang pakej yang bercanggah terlebih dahulu. Ini adalah senarai yang didokumenkan oleh Docker untuk RHEL:

sudo dnf remove docker docker-client docker-client-latest docker-common \
  docker-latest docker-latest-logrotate docker-logrotate docker-engine podman runc

Baca apa yang dirancang oleh dnf sebelum anda mengesahkannya. Pada imej VPS yang baharu, senarai tersebut adalah pendek. Pada kotak yang telah digunakan oleh seseorang, membuang podman boleh menarik keluar cockpit-podman atau alat lain yang bergantung padanya.

Mengekalkan podman bersama Docker adalah mungkin pada dasarnya: buang hanya podman-docker, supaya nama docker bebas, dan runc, yang digantikan oleh pakej containerd.io. Dokumentasi Docker menganggap podman sebagai pakej yang bercanggah, jadi susun atur ini tidak disokong oleh Docker. Jika pemasangan masih melaporkan konflik, gunakan senarai pembuangan penuh di atas.

Menambah repositori Docker dengan dnf config-manager

Docker menerbitkan RPM untuk Enterprise Linux di download.docker.com. Fail repositori tersebut menghala ke tree CentOS, iaitu tree yang digunakan oleh Rocky Linux dan AlmaLinux untuk resolusi. Disemak pada Ogos 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.repo

Versi 5 bagi dnf telah membuang argumen --add-repo, jadi arahan kedua itu akan gagal pada keluaran yang lebih baharu. Semak versi yang anda miliki, kemudian pilih bentuk yang sepadan:

dnf --version

Jika ia memaparkan versi 5.x, gunakan bentuk subperintah sebaliknya:

sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/centos/docker-ce.repo

Kedua-duanya menulis fail yang sama ke /etc/yum.repos.d/docker-ce.repo. Bentuk yang salah akan gagal dengan ralat argumen tidak dikenali dan bukannya melakukan sesuatu yang salah secara senyap, jadi anda tidak akan terlepas perkara ini.

Fail repo tersebut menetapkan baseurl kepada laluan yang mengandungi $releasever, dan dnf mengembangkan pemboleh ubah itu daripada pakej keluaran anda. Rocky Linux dan AlmaLinux menetapkannya kepada nombor versi major, jadi 9 pada EL 9 dan 10 pada EL 10, itulah sebabnya repositori CentOS dapat diselesaikan dengan betul pada sistem Rocky. Sahkan pengembangan tersebut sebelum anda memasang:

sudo dnf repoinfo docker-ce-stable

Baca baris Repo-baseurl. Ia sepatutnya berakhir dengan /9/x86_64/stable atau /10/x86_64/stable. Jika keluaran anda menetapkan $releasever kepada versi point seperti 9.6, dnf akan melaporkan Status code: 404 untuk URL tersebut apabila ia mengambil metadata. Betulkan dengan menyunting /etc/yum.repos.d/docker-ce.repo dan menggantikan $releasever dengan nombor major sahaja.

Pasang enjin dan pemalam compose

sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Terdapat lima pakej, dan setiap satunya mempunyai satu tugas. docker-ce ialah daemon, dockerd. docker-ce-cli ialah arahan docker yang anda taip. containerd.io ialah runtime kontena yang dipacu oleh daemon tersebut. docker-buildx-plugin membina imej. docker-compose-plugin menyediakan docker compose sebagai sub-arahan.

Pakej-pakej ini tidak memasang binari docker-compose yang menggunakan tanda sempang. Itu adalah Compose v1, yang telah mencapai penghujung hayat pada Julai 2023. Mana-mana arahan yang memanggil docker-compose dengan tanda sempang perlu dikemas kini kepada docker compose dengan ruang kosong.

Pemasangan pertama akan berhenti untuk mengimport kunci tandatangan Docker dan menunjukkan cap jarinya kepada anda. Kunci tersebut datang daripada gpgkey=https://download.docker.com/linux/centos/gpg dalam fail repo yang baru anda tambah, jadi bandingkan cap jari yang dicetak oleh dnf dengan URL tersebut sebelum anda menerimanya.

Satu kegagalan sering berlaku sehingga perlu dinyatakan. Jika dnf melaporkan bahawa containerd.io memerlukan container-selinux dan tiada apa yang menyediakannya, repositori AppStream anda telah dinyahdayakan. Jalankan dnf repolist dan pastikan appstream disenaraikan, kerana di situlah container-selinux dibekalkan pada EL 9 dan EL 10.

Mulakan Docker dan sahkan ia berjalan

sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker run --rm hello-world

Pakej RPM Docker membiarkan daemon dalam keadaan berhenti dan dinyahdayakan selepas pemasangan. Inilah sebabnya langkah ini muncul pada halaman CentOS Docker dan bukan pada halaman Ubuntu, di mana fail deb memulakan servis untuk anda. Abaikan enable dan Docker akan berjalan sehingga but semula seterusnya, kemudian ia akan kekal berhenti dan menyebabkan setiap kontena turut terhenti.

systemctl status sepatutnya memaparkan Active: active (running). Kontena hello-world sepatutnya mencetak This message shows that your installation appears to be working correctly. dan keluar. Jika ia sebaliknya mencetak ralat kebenaran pada /var/run/docker.sock, anda tertinggal sudo, yang akan dibetulkan oleh bahagian kumpulan docker di bawah.

Semak pemalam compose secara berasingan, kerana ia merupakan pakej yang berbeza dan mungkin tiada walaupun enjin berada dalam keadaan baik:

docker compose version

Jawapan yang sihat kelihatan seperti Docker Compose version v2.x.x. Mendapatkan semula servis anda selepas but semula adalah soalan yang berasingan daripada mendayakan daemon, dan polisi mulakan semula menentukan sama ada servis Compose kembali berjalan semasa but.

Mengapa bind mount memberikan ralat permission denied?

Rocky Linux dan AlmaLinux menjalankan SELinux (Security-Enhanced Linux) dalam mod enforcing secara lalai. Sahkan perkara ini dengan getenforce, yang akan memaparkan Enforcing.

Kontena Docker berjalan di bawah jenis SELinux container_t, dan jenis tersebut hanya boleh membaca serta menulis fail yang dilabelkan sebagai container_file_t. Direktori yang anda cipta pada hos membawa label yang diwarisi daripada laluan induknya, yang bukanlah container_file_t. Kontena akan dinafikan akses walaupun pemilik, kumpulan dan mod kelihatan betul dari sisi hos. Anda boleh menghasilkan semula ralat ini dengan tiga arahan:

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.html

Kontena akan memaparkan:

cat: can't open '/usr/share/nginx/html/index.html': Permission denied

Dua arahan akan menunjukkan puncanya kepada anda. ls -ldZ /srv/site memaparkan label tersebut, yang bagi laluan di bawah /srv adalah system_u:object_r:var_t:s0, bukannya container_file_t. Kemudian, sudo ausearch -m avc -ts recent memaparkan rekod audit kernel, yang mengandungi avc: denied { read }, medan scontext= yang menamakan container_t, serta medan tcontext= yang menamakan label yang baru sahaja anda lihat pada direktori tersebut. Ketidakpadanan antara kedua-dua medan itulah puncanya.

Penyelesaiannya adalah dengan menambah akhiran pada argumen volume. Docker akan melabelkan semula laluan tersebut untuk anda:

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 melabelkan semula kandungan sebagai dikongsi (shared), supaya beberapa kontena boleh menggunakan direktori yang sama. :Z dalam huruf besar melabelkannya sebagai peribadi dan tidak dikongsi (private), terikat kepada satu kontena sahaja, dan kontena kedua yang membaca laluan yang sama akan dinafikan akses. Gunakan :z untuk sebarang perkara yang turut dicapai oleh sidecar atau kontena sandaran. Gunakan :Z untuk direktori pangkalan data yang dimiliki oleh satu kontena sahaja.

Dokumentasi Docker mengandungi amaran yang perlu diulangi, kerana proses pelabelan semula adalah secara rekursif. Melakukan bind-mount pada direktori sistem seperti /home atau /usr dengan :Z akan "menyebabkan mesin hos anda tidak boleh beroperasi dan anda mungkin perlu melabelkan semula fail mesin hos secara manual". Halakan akhiran ini hanya pada direktori yang anda cipta untuk kontena, jangan sekali-kali pada laluan sistem.

Dalam Compose, akhiran tersebut diletakkan pada rentetan yang sama:

services:
  web:
    image: nginx:alpine
    volumes:
      - /srv/site:/usr/share/nginx/html:ro,z

Terdapat dua had yang mudah tersilap langkah. Flag --mount tidak boleh menetapkan label SELinux sama sekali, jadi gunakan -v apabila anda memerlukannya. Named volumes tidak memerlukan akhiran, kerana Docker melabelkan sendiri direktori yang diciptanya di bawah /var/lib/docker/volumes.

Jangan matikan SELinux. Gunakan sudo setenforce 0 hanya sebagai ujian selama satu minit: jika kontena berfungsi selepas itu, masalahnya adalah pada label dan :z adalah jawapannya. Kembalikan semula kepada mod asal dengan sudo setenforce 1 dengan segera. Pada Enterprise Linux, permission denied pada bind mount mempunyai dua punca berasingan yang kelihatan sama dari dalam kontena. Satu adalah label SELinux. Satu lagi adalah pemilikan pengguna dan kumpulan berangka biasa, iaitu perkara yang diselesaikan oleh pemboleh ubah PUID dan PGID. ls -lnZ menunjukkan kepada anda mod, pemilik berangka dan label dalam satu baris, supaya anda boleh mengenal pasti punca masalah yang sedang dihadapi.

Mengapa port yang diterbitkan boleh dicapai sedangkan firewalld kelihatan tertutup?

Firewalld ialah tembok api lalai pada Rocky Linux dan AlmaLinux. Semak sama ada ia sedang berjalan dengan sudo systemctl is-active firewalld. Sekarang, terbitkan satu port dan lihat apakah port yang dianggap terbuka oleh firewalld:

sudo docker run -d --name web -p 8080:80 nginx:alpine
sudo firewall-cmd --list-ports

firewall-cmd mencetak baris kosong. Dari mesin lain, curl -I http://YOUR_SERVER_IP:8080/ mengembalikan HTTP/1.1 200 OK. Port tersebut terbuka kepada internet dan tembok api anda tidak melaporkan apa-apa.

Puncanya ialah laluan yang diambil oleh paket tersebut. Peraturan zon firewalld menapis trafik yang ditujukan kepada hos itu sendiri. Port yang diterbitkan tidak ditujukan kepada hos: Docker memasang peraturan destination NAT (network address translation) yang menulis semula destinasi kepada alamat kontena sebelum paket sampai ke laluan input hos, jadi kernel memajukan (forward) paket tersebut dan bukannya menghantarnya secara setempat. Docker kemudian meletakkan antara muka jambatannya ke dalam zon firewalld yang dipanggil docker yang sasarannya ialah ACCEPT, dan menambah polisi pemajuan yang dipanggil docker-forwarding yang membenarkan pemajuan daripada mana-mana zon ke dalam zon docker. Peraturan zon anda tidak pernah melihat paket tersebut.

Penyelesaian paling bersih tidak memerlukan peraturan tembok api. Ikat (bind) bahagian hos bagi penerbitan tersebut kepada loopback dan letakkan reverse proxy di hadapannya:

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 setempat mengembalikan HTTP/1.1 200 OK dan permintaan yang sama daripada mesin lain tidak lagi bersambung. Apa-apa sahaja tanpa alamat hos dalam argumen -p diterbitkan pada setiap antara muka, jadi anggap -p 8080:80 kosong sebagai keputusan untuk mendedahkan servis tersebut kepada umum.

Apabila anda benar-benar memerlukan servis yang boleh dicapai daripada alamat tertentu dan bukan yang lain, Docker menyimpan satu chain untuk anda. DOCKER-USER diproses sebelum peraturan accept milik Docker sendiri, jadi peraturan yang anda letakkan di sana akan kekal walaupun Docker dimulakan semula dan menulis semula chain miliknya:

sudo iptables -I DOCKER-USER -i enp1s0 ! -s 203.0.113.10 -j DROP
sudo iptables -S DOCKER-USER

Ambil nama antara muka daripada ip route show default dan bukannya mengandaikan eth0, kerana imej EL semasa menggunakan nama seperti enp1s0 atau ens3. Pada Rocky dan AlmaLinux, arahan iptables ialah lapisan keserasian di atas nftables, dan chain Docker boleh dilihat melaluinya. Peraturan yang ditambah dengan cara ini akan hilang selepas but semula melainkan anda menyimpannya, jadi tulis peraturan tersebut ke dalam unit systemd sebaik sahaja anda berpuas hati dengannya.

Docker Engine 28.0, yang dikeluarkan pada 2025, menutup satu kelemahan berkaitan: akses laluan terus ke port kontena yang tidak pernah diterbitkan kini disekat dalam chain DOCKER. Perubahan itu tidak menjejaskan port yang diterbitkan, jadi semua perkara di atas masih terpakai pada versi semasa. Satu tabiat operasi yang wajar dibentuk: selepas sebarang sudo firewall-cmd --reload, uji semula port yang diterbitkan. Jika ia berhenti menjawab, sudo systemctl restart docker akan memasang semula peraturan Docker.

Pentadbir Ubuntu menghadapi halangan yang sama melalui alat yang berbeza, yang diterangkan dalam mengapa port Docker yang diterbitkan mengabaikan peraturan ufw. Laluan NAT adalah puncanya dalam kedua-dua kes. Hanya tembok api di hadapannya yang berbeza.

Menambah pengguna bukan root ke dalam kumpulan docker

Menaip sudo sebelum setiap arahan docker akan menjadi leceh, dan kumpulan docker menghapuskan keperluan tersebut:

sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world

usermod -aG menyunting /etc/group, namun shell semasa anda sudah mempunyai senarai kumpulannya sendiri, jadi perubahan tersebut tidak akan berkuat kuasa sehingga anda mendapatkan shell yang baharu. newgrp docker memulakan shell dengan kumpulan tersebut dilampirkan supaya anda boleh mengujinya dengan segera. Sesi SSH baharu akan mengambil tetapan ini secara automatik.

Fahami dengan jelas apa yang diberikan oleh kumpulan tersebut. Keahlian memberikan akses tulis kepada /var/run/docker.sock, dan mana-mana entiti yang boleh berhubung dengan soket tersebut boleh mengarahkan daemon untuk memulakan kontena yang melekapkan (mount) sistem fail hos. Satu arahan menunjukkan maksudnya:

docker run --rm -v /:/host alpine wc -l /host/etc/shadow

Arahan itu membaca fail yang hanya boleh dibaca oleh root, daripada akaun yang tidak mempunyai hak sudo. Dokumentasi pasca-pemasangan Docker sendiri menyatakan perkara yang sama: kumpulan docker memberikan keistimewaan yang setara dengan root. Tambahkan akaun ke dalamnya hanya jika anda juga sanggup memberikan akaun tersebut sudo. Jika anda sedang menyediakan akaun pada pelayan baharu, buat keputusan ini bersama-sama dengan penyediaan pengguna dengan keistimewaan minimum pada VPS dan bukannya selepas segalanya selesai.

Docker juga menyediakan mod rootless yang menjalankan daemon sebagai pengguna tanpa keistimewaan. Ia merupakan laluan pemasangan yang berasingan dan ia mengubah cara pemacu storan serta port di bawah 1024 berfungsi, jadi rancanglah ia sebagai projek tersendiri dan bukannya sebagai flag yang ditambah kemudian.

Langkah seterusnya

Anda kini mempunyai enjin, pemalam compose, servis yang kekal aktif selepas but semula, serta tiga kelakuan khusus EL yang didokumentasikan di atas. Langkah seterusnya ialah compose.yaml bagi setiap servis, dan anatomi fail Compose merangkumi format fail serta arahan yang menggerakkannya. Jika ini merupakan hos kontena pertama anda, menjalankan Docker pada VPS merangkumi persoalan mengenai saiz, storan dan kebersihan imej yang tidak disentuh dalam panduan ini.

FAQ

Adakah repositori CentOS untuk Docker berfungsi pada Rocky Linux dan AlmaLinux?

Ya. Tambahkan https://download.docker.com/linux/centos/docker-ce.repo menggunakan dnf config-manager. baseurl dalam fail tersebut mengandungi $releasever, dan Rocky Linux serta AlmaLinux akan mengembangkannya kepada nombor versi utama. Oleh itu, sistem EL 9 akan merujuk kepada tree CentOS 9 dan sistem EL 10 kepada tree CentOS 10. Sahkan pengembangan ini dengan sudo dnf repoinfo docker-ce-stable dan baca baris Repo-baseurl. Status code: 404 semasa dnf mengambil metadata bermakna pemboleh ubah tersebut berkembang kepada point release, dan menyunting /etc/yum.repos.d/docker-ce.repo untuk menggunakan nombor utama sahaja akan membetulkannya.

Bolehkah Docker dan podman dipasang pada pelayan yang sama?

Dokumentasi Docker menyenaraikan podman dan runc sebagai pakej yang bercanggah dan mengarahkan anda untuk membuang kedua-duanya sebelum memasang Docker Engine. Percanggahan sebenar adalah pada pakej podman-docker, yang memiliki /usr/bin/docker dan menukarkan setiap arahan docker menjadi arahan podman. Jalankan rpm -qf "$(command -v docker)" untuk melihat pakej mana yang memiliki laluan tersebut. Jika output bermula dengan podman-docker, podman yang sedang menjawab. Mengekalkan kedua-dua enjin bukanlah susun atur yang disokong oleh Docker, jadi pada pelayan yang penting, pilih salah satu sahaja.

Mengapa kontena saya mendapat ralat permission denied pada bind mount?

SELinux dikuatkuasakan secara lalai pada Rocky Linux dan AlmaLinux. Kontena berjalan sebagai jenis container_t dan hanya boleh menyentuh fail yang dilabelkan sebagai container_file_t. Oleh itu, direktori yang anda cipta membawa label yang salah dan akses dinafikan tanpa mengira pemilik dan mod fail tersebut. Sahkan perkara ini dengan ls -ldZ pada laluan hos dan sudo ausearch -m avc -ts recent, yang mencetak avc: denied dengan dua konteks yang tidak sepadan. Tambahkan :z pada argumen volume untuk kandungan yang dikongsi antara kontena, atau :Z untuk kandungan yang peribadi kepada satu kontena. Jangan sekali-kali menghalakan :Z ke /home atau /usr, kerana pelabelan semula adalah rekursif dan akan merosakkan hos.

Adakah saya perlu membuka port dalam firewalld untuk menerbitkan port kontena?

Tidak, dan itulah masalahnya. Peraturan NAT Docker menulis semula alamat destinasi sebelum paket sampai ke laluan input hos, jadi peraturan zon firewalld tidak akan memeriksanya. Docker juga meletakkan bridge miliknya dalam zon firewalld yang dipanggil docker dengan sasaran ACCEPT. Kontena yang dimulakan dengan -p 8080:80 boleh dicapai dari internet walaupun sudo firewall-cmd --list-ports tidak mencetak apa-apa. Terbitkan ke alamat tertentu dengan -p 127.0.0.1:8080:80 apabila hanya hos yang sepatutnya mencapai servis tersebut, atau masukkan peraturan penapisan ke dalam chain DOCKER-USER, yang diproses oleh Docker sebelum peraturan terima (accept) miliknya sendiri.

Adakah selamat untuk menambah pengguna saya ke dalam kumpulan docker?

Ia memberikan akses root. Ahli kumpulan docker boleh menulis ke /var/run/docker.sock, dan docker run --rm -v /:/host alpine wc -l /host/etc/shadow kemudian membaca fail yang hanya boleh diakses oleh root daripada akaun yang tidak mempunyai hak sudo. Dokumentasi pasca-pemasangan Docker menyatakan kesetaraan yang sama. Hanya tambahkan akaun yang anda sudah percayai dengan sudo, dan teruskan menggunakan sudo docker untuk akaun kongsi atau akaun servis. Mod rootless adalah alternatif apabila anda memerlukan kontena di bawah pengguna tanpa keistimewaan, dan ia merupakan laluan pemasangan yang berasingan dan bukannya sekadar tetapan.