Paano Mag-install ng Docker sa Rocky Linux o AlmaLinux
I-install ang Docker Engine gamit ang dnf sa Rocky Linux o AlmaLinux. Ayusin ang error na docker command ay pagmamay-ari ng Podman at SELinux bind mounts.
Mag-install ng Docker sa Rocky Linux at AlmaLinux
Para mag-install ng Docker sa Rocky Linux o AlmaLinux, idagdag ang sariling dnf repository ng Docker, i-install ang engine kasama ang compose plugin, at i-enable ang service. Apat na command lang ang bahaging ito, at pareho ito sa dalawang distribution dahil parehong rebuild ng Red Hat Enterprise Linux (RHEL) ang mga ito at pareho ang package layout. Pareho rin ang proseso sa CentOS Stream.
Maikli ang installation, kaya karamihan sa gabay na ito ay tumatalakay sa mga pagkakaiba ng Enterprise Linux (EL) sa Ubuntu. Maaaring ginagamit na ng Podman ang docker command sa image mo. Bina-block ng SELinux ang mga file na naka-bind-mount hanggang sa magkaroon ang mga ito ng tamang label. Hindi sinasala ng Firewalld ang mga published port ng Docker, kaya maaaring bukas sa internet ang container port habang iniuulat ng firewall-cmd na walang bukas na port.
Huwag gamitin ang convenience script ng Docker mula sa get.docker.com. Sinasabi sa sariling documentation ng Docker na hindi ito inirerekomenda para sa production. Binabago nito ang repository configuration nang hindi nagtatanong, at hindi ito ligtas i-run muli para sa upgrade. Kapag mano-mano mong idinagdag ang repository, tinatrato ng dnf upgrade ang Docker tulad ng iba pang package sa server.
Nakasagot na ba ang podman sa docker command?
Kasama ang podman sa mga default repository ng Rocky Linux at AlmaLinux, at maraming VPS image ang awtomatikong nag-i-install nito. May ilang image na nag-i-install pa ng podman-docker, na naglalagay ng shell script sa /usr/bin/docker na tumatawag sa podman. Dahil dito, ang bawat docker command na tina-type mo ay podman ang aktuwal na nagpapatakbo. Kaya ang isang guide para sa Docker ay maaaring maglabas ng output na hindi mo inaasahan.
Ang unang palatandaan ay isang banner. Sinusuri ng /usr/bin/docker script kung umiiral ang file na /etc/containers/nodocker. Kapag wala ang file, nagpi-print ito ng isang linya bago magpatakbo ng anuman:
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.Maaaring may gumawa ng file na iyon upang itago ang banner, kaya huwag umasa rito lamang. Gamitin ang package database upang malaman kung aling package ang nagmamay-ari ng binary:
command -v docker
rpm -qf "$(command -v docker)"Kapag nagsisimula sa podman-docker ang sagot, podman ang sumasagot sa command. Kapag nagsisimula sa docker-ce-cli ang sagot, tunay na Docker ang ginagamit. Kung iniulat ng rpm -qf na walang package na nagmamay-ari sa file, maaaring mano-manong na-install ito. Basahin muna ang script bago ito pagkatiwalaan.
Parehong OCI image ang pinapatakbo ng Podman, at makatwirang piliin ito. Kung ito ang gusto mo, maaari kang huminto rito. Kung Docker Engine ang gusto mo, alisin muna ang mga package na nagkakaroon ng conflict. Ito ang listahang idinodokumento ng Docker para sa RHEL:
sudo dnf remove docker docker-client docker-client-latest docker-common \
docker-latest docker-latest-logrotate docker-logrotate docker-engine podman runcBasahin muna kung ano ang aalisin ng dnf bago mo kumpirmahin. Sa bagong VPS image, karaniwang maikli ang listahan. Sa isang server na nagamit na, maaaring alisin ng pagtanggal sa podman ang cockpit-podman o ibang tool na umaasa rito.
Sa prinsipyo, maaaring panatilihin ang podman kasabay ng Docker: podman-docker lamang ang alisin upang maging available ang pangalang docker, pati ang runc na pinapalitan ng containerd.io package. Itinuturing ng documentation ng Docker ang podman bilang conflicting package, kaya hindi suportado ng Docker ang ganitong setup. Kung mag-ulat pa rin ng conflict ang installation, gamitin ang buong listahan ng pagtanggal sa itaas.
Magdagdag ng Docker repository gamit ang dnf config-manager
Naglalabas ang Docker ng mga RPM para sa Enterprise Linux sa download.docker.com. Tinutukoy ng repository file ang CentOS tree, na siyang ginagamit ng Rocky Linux at AlmaLinux. Sinuri noong August 2026, at inililista ng Docker ang repository na ito para sa CentOS Stream 9 at CentOS Stream 10.
sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repoInalis ng version 5 ng dnf ang argument na --add-repo, kaya mabibigo ang ikalawang command sa mga mas bagong release. Suriin kung aling version ang mayroon ka, pagkatapos ay gamitin ang katugmang anyo:
dnf --versionKung mag-print ito ng 5.x version, gamitin sa halip ang subcommand form:
sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/centos/docker-ce.repoParehong isinusulat ng mga ito ang parehong file sa /etc/yum.repos.d/docker-ce.repo. Mabibigo ang maling anyo na may unknown-argument error sa halip na gumawa ng tahimik na maling pagbabago, kaya mapapansin mo agad ang problema.
Itinatakda ng repo file na iyon ang baseurl sa isang path na naglalaman ng $releasever, at ine-expand ng dnf ang variable na iyon mula sa release package mo. Itinatakda ito ng Rocky Linux at AlmaLinux sa major version number, kaya 9 ito sa EL 9 at 10 sa EL 10. Ito ang dahilan kung bakit tamang nare-resolve ang CentOS repository sa isang Rocky box. Kumpirmahin ang expansion bago mag-install:
sudo dnf repoinfo docker-ce-stableBasahin ang linyang Repo-baseurl. Dapat itong magtapos sa /9/x86_64/stable o /10/x86_64/stable. Kung itinatakda ng release mo ang $releasever sa point version gaya ng 9.6, iuulat ng dnf ang Status code: 404 para sa URL na iyon kapag kumukuha ito ng metadata. Ayusin ito sa pamamagitan ng pag-edit sa /etc/yum.repos.d/docker-ce.repo at pagpapalit ng $releasever sa bare major number.
I-install ang engine at ang compose plugin
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginLimang package ito, at may kanya-kanyang tungkulin ang bawat isa. Ang docker-ce ang daemon, ang dockerd. Ang docker-ce-cli ang docker command na ita-type mo. Ang containerd.io ang container runtime na pinapatakbo ng daemon. Gumagawa ng images ang docker-buildx-plugin. Ibinibigay ng docker-compose-plugin ang docker compose bilang subcommand.
Hindi nag-i-install ang mga package na ito ng hyphenated na docker-compose binary. Ito ang Compose v1, na nag-end of life noong July 2023. Kailangang i-update ang anumang tumatawag sa docker-compose na may hyphen upang gamitin ang docker compose na may space.
Hihinto ang unang install upang i-import ang signing key ng Docker at ipapakita ang fingerprint nito. Galing ang key sa gpgkey=https://download.docker.com/linux/centos/gpg na nasa repo file na idinagdag mo, kaya ihambing ang fingerprint na ipinapakita ng dnf sa URL na iyon bago mo ito tanggapin.
May isang failure na madalas lumitaw kaya dapat itong malaman. Kung mag-ulat ang dnf na kailangan ng containerd.io ang container-selinux at walang nagbibigay nito, naka-disable ang AppStream repository mo. Patakbuhin ang dnf repolist at kumpirmahing nakalista ang appstream, dahil doon nire-release ang container-selinux sa EL 9 at EL 10.
Simulan ang Docker at kumpirmahing tumatakbo ito
sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker run --rm hello-worldIniiwang nakahinto at naka-disable ng RPM packages ng Docker ang daemon pagkatapos ng installation. Kaya nasa CentOS page ng Docker ang hakbang na ito, pero wala sa Ubuntu page nito, kung saan awtomatikong sinisimulan ng deb ang service. Laktawan ang enable at tatakbo ang Docker hanggang sa susunod na reboot. Pagkatapos nito, mananatili itong nakahinto at hihilahin nitong pababa ang lahat ng container.
Dapat ipakita ng systemctl status ang Active: active (running). Dapat i-print ng hello-world container ang This message shows that your installation appears to be working correctly. at pagkatapos ay mag-exit. Kung permission error naman ang i-print nito sa /var/run/docker.sock, hindi mo isinama ang sudo. Inaayos ito ng seksiyon tungkol sa docker group sa ibaba.
Hiwalay na suriin ang compose plugin dahil ibang package ito at maaaring wala ito kahit maayos ang engine:
docker compose versionAng maayos na resulta ay katulad ng Docker Compose version v2.x.x. Hiwalay na usapin ang pagpapanumbalik ng mga service pagkatapos ng reboot sa pag-enable ng daemon, at ang restart policies ang nagtatakda kung babalik ang mga Compose service sa pag-boot.
Bakit nagkakaroon ng permission denied ang bind mount?
Pinapatakbo ng Rocky Linux at AlmaLinux ang SELinux (Security-Enhanced Linux) sa enforcing mode bilang default. Kumpirmahin ito gamit ang getenforce, na nagpi-print ng Enforcing.
Tumatakbo ang Docker containers sa ilalim ng SELinux type na container_t, at maaari lamang magbasa at magsulat ang type na iyon sa mga file na may label na container_file_t. Ang directory na ginawa mo sa host ay may label na minana mula sa parent path nito, at hindi ito container_file_t. Idinedeny ang container kahit mukhang tama ang owner, group, at mode mula sa host. I-reproduce ito gamit ang tatlong command:
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.htmlIni-print ng container ang:
cat: can't open '/usr/share/nginx/html/index.html': Permission deniedDalawang command ang magpapakita ng sanhi. Ini-print ng ls -ldZ /srv/site ang label, na para sa path sa ilalim ng /srv ay system_u:object_r:var_t:s0, hindi container_file_t. Pagkatapos, ini-print ng sudo ausearch -m avc -ts recent ang audit record ng kernel. Naglalaman ito ng avc: denied { read }, isang scontext= field na tumutukoy sa container_t, at isang tcontext= field na tumutukoy sa label na nakita mo sa directory. Ang mismatch sa pagitan ng dalawang field na ito ang buong sanhi.
Ang fix ay isang suffix sa volume argument. Awtomatikong nire-relabel ng Docker ang path:
sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro,z nginx:alpine cat /usr/share/nginx/html/index.htmlAng :z na lowercase ay nagre-relabel ng content bilang shared, kaya magagamit ng maraming container ang parehong directory. Ang :Z na uppercase ay nagre-relabel dito bilang private at unshared, at nakatali sa isang container. Kapag binasa ng pangalawang container ang parehong path, idinedeny ito. Gamitin ang :z para sa anumang directory na ginagamit din ng sidecar o backup container. Gamitin ang :Z para sa database directory na pagmamay-ari ng isang container.
May babala sa documentation ng Docker na dapat ulitin dahil recursive ang relabel. Kapag nag-bind-mount ng system directory gaya ng /home o /usr gamit ang :Z, “maaaring maging hindi na gumagana ang host machine at maaaring kailanganin mong manu-manong i-relabel ang mga file ng host machine.” Ituro ang mga suffix na ito sa mga directory na ginawa mo para sa container, at huwag kailanman sa system path.
Sa Compose, ilagay ang suffix sa parehong string:
services:
web:
image: nginx:alpine
volumes:
- /srv/site:/usr/share/nginx/html:ro,zMay dalawang limit na madaling makaligtaan. Hindi makakapagtakda ng SELinux label ang --mount flag, kaya gamitin ang -v kapag kailangan mo nito. Hindi kailangan ng suffix ng named volumes dahil awtomatikong nilalagyan ng Docker ng label ang mga directory na ginagawa nito sa ilalim ng /var/lib/docker/volumes.
Huwag i-disable ang SELinux. Gamitin lamang ang sudo setenforce 0 bilang isang minutong test. Kung gumana ang container pagkatapos nito, label ang problema at :z ang sagot. Ibalik agad ito gamit ang sudo setenforce 1. Sa Enterprise Linux, may dalawang magkahiwalay na sanhi ang permission denied sa bind mount na magkapareho ang hitsura mula sa loob ng container. Ang isa ay ang SELinux label. Ang isa pa ay ordinaryong numeric user at group ownership. Ito ang problemang nilulutas ng mga PUID at PGID variable. Ipinapakita ng ls -lnZ ang mode, numeric owner, at label sa isang linya, kaya matutukoy mo kung alin ang kailangang ayusin.
Bakit naa-access ang published port kahit mukhang sarado ang firewalld?
Ang firewalld ang default firewall sa Rocky Linux at AlmaLinux. Suriin kung tumatakbo ito gamit ang sudo systemctl is-active firewalld. Ngayon, mag-publish ng port at tingnan kung ano ang itinuturing na bukas ng firewalld:
sudo docker run -d --name web -p 8080:80 nginx:alpine
sudo firewall-cmd --list-portsNagpi-print ang firewall-cmd ng walang laman na linya. Mula sa ibang machine, nagbabalik ang curl -I http://YOUR_SERVER_IP:8080/ ng HTTP/1.1 200 OK. Bukas sa internet ang port, pero walang naiulat ang firewall mo.
Ang sanhi ay ang dinaanang path ng packet. Sinasala ng mga zone rule ng firewalld ang traffic na direktang nakalaan sa host mismo. Hindi nakalaan sa host ang published port: nag-i-install ang Docker ng destination NAT (network address translation) rule na nire-rewrite ang destination papunta sa address ng container bago makarating ang packet sa input path ng host. Dahil dito, ipinapasa ng kernel ang packet sa halip na ihatid ito locally. Inilalagay din ng Docker ang bridge interface nito sa firewalld zone na tinatawag na docker, na ang target ay ACCEPT, at nagdaragdag ng forwarding policy na tinatawag na docker-forwarding na nagpapahintulot ng forwarding mula sa anumang zone papunta sa docker zone. Hindi nakikita ng mga zone rule mo ang packet.
Ang pinakamalinis na fix ay hindi nangangailangan ng firewall rule. I-bind ang host side ng publish sa loopback at maglagay ng reverse proxy sa harap nito:
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/Nagbabalik ang lokal na curl ng HTTP/1.1 200 OK, at hindi na kumokonekta ang parehong request mula sa ibang machine. Kapag walang host address sa argumentong -p, pino-publish ang port sa bawat interface. Kaya ituring ang bare na -p 8080:80 bilang desisyong gawing publicly accessible ang service.
Kapag kailangan mong maabot ang isang service mula sa ilang address pero hindi mula sa iba, naglalaan ang Docker ng chain para sa iyo. Pinoproseso ang DOCKER-USER bago ang sarili nitong accept rule ng Docker. Kaya mananatili roon ang rule na inilagay mo kahit mag-restart ang Docker at i-rewrite ang mga chain nito:
sudo iptables -I DOCKER-USER -i enp1s0 ! -s 203.0.113.10 -j DROP
sudo iptables -S DOCKER-USERKunin ang pangalan ng interface mula sa ip route show default sa halip na ipagpalagay na eth0, dahil gumagamit ang kasalukuyang EL image ng mga pangalang gaya ng enp1s0 o ens3. Sa Rocky at AlmaLinux, ang command na iptables ay compatibility layer para sa nftables, at makikita rito ang mga chain ng Docker. Mawawala ang mga rule na idinagdag sa ganitong paraan pagkatapos ng reboot maliban kung ise-save mo ang mga ito. Kaya ilagay ang mga ito sa isang systemd unit kapag nasubukan mo na at maayos na ang mga ito.
Isinara ng Docker Engine 28.0, na inilabas noong 2025, ang kaugnay na butas kung saan direktang naa-access sa routed path ang mga container port na hindi kailanman na-publish. Bina-block na ito ngayon sa DOCKER chain. Hindi naaapektuhan ng pagbabagong iyon ang mga published port, kaya naaangkop pa rin ang lahat ng nasa itaas sa kasalukuyang mga version. Mabuting gawing regular na hakbang ang sumusunod: pagkatapos ng anumang sudo firewall-cmd --reload, subukang muli ang isang published port. Kung tumigil itong sumagot, muling ini-install ng sudo systemctl restart docker ang mga rule ng Docker.
Nararanasan din ng mga administrator ng Ubuntu ang parehong problema sa ibang tool. Ito ang kung bakit binabalewala ng mga published Docker port ang mga rule ng ufw. Ang NAT path ang sanhi sa parehong kaso. Ang firewall lamang na nasa unahan nito ang naiiba.
Magdagdag ng non-root user sa docker group
Nakakasawa nang i-type ang sudo bago ang bawat docker command, at inaalis ng docker group ang pangangailangang ito:
sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-worldIno-edit ng usermod -aG ang /etc/group, pero mayroon nang group list ang kasalukuyang shell mo. Kaya hindi agad nalalapat ang pagbabago hanggang makakuha ka ng bagong shell. Nagbubukas ang newgrp docker ng shell na kasama ang group, kaya masusubukan mo agad ito. Awtomatikong makukuha ito ng mga bagong SSH session.
Tiyaking malinaw sa iyo kung anong access ang ibinibigay ng group na ito. Nagbibigay ang membership ng write access sa /var/run/docker.sock. Anumang makakakonekta sa socket na iyon ay maaaring humiling sa daemon na magsimula ng container na nag-mount ng filesystem ng host. Ipinapakita ng isang command kung ano ang ibig sabihin nito:
docker run --rm -v /:/host alpine wc -l /host/etc/shadowBinabasa nito ang isang file na root lamang ang maaaring magbasa, gamit ang account na walang sudo rights. Pareho ang sinasabi sa post-install documentation ng Docker: ang docker group ay nagbibigay ng mga privilege na katumbas ng root. Magdagdag lamang ng account dito kung ibibigay mo rin sa account na iyon ang sudo. Kung nagse-set up ka ng mga account sa isang bagong server, pagpasiyahan ito kasabay ng iba pang bahagi ng iyong least-privilege user setup sa isang VPS, sa halip na ayusin ito pagkatapos.
May rootless mode din ang Docker na nagpapatakbo sa daemon bilang unprivileged user. Hiwalay itong installation path, at binabago nito kung paano gumagana ang storage drivers at ang mga port na mas mababa sa 1024. Kaya planuhin ito bilang sarili nitong proyekto, hindi bilang flag na idaragdag mo sa hinaharap.
Susunod na hakbang
Mayroon ka na ngayong engine, Compose plugin, isang service na nagpapatuloy kahit mag-reboot, at ang tatlong behavior na partikular sa EL na nakadokumento sa itaas. Ang susunod na hakbang ay isang compose.yaml bawat service. Sinasaklaw ng anatomy ng Compose file ang format ng file at ang mga command na nagpapatakbo nito. Kung ito ang una mong container host, sinasaklaw ng pagpapatakbo ng Docker sa isang VPS ang mga tanong tungkol sa sizing, storage, at image hygiene na hindi tinalakay ng gabay na ito.
FAQ
Gumagana ba ang Docker's CentOS repository sa Rocky Linux at AlmaLinux?
Oo. Idagdag ang https://download.docker.com/linux/centos/docker-ce.repo gamit ang dnf config-manager. Ang baseurl sa file na iyon ay naglalaman ng $releasever, at ine-expand ito ng Rocky Linux at AlmaLinux sa major version number. Kaya nagre-resolve ang isang EL 9 machine sa CentOS 9 tree, at ang isang EL 10 machine sa CentOS 10 tree. Kumpirmahin ang expansion gamit ang sudo dnf repoinfo docker-ce-stable at basahin ang linyang Repo-baseurl. Ang Status code: 404 habang kumukuha ng metadata ang dnf ay nangangahulugang na-expand ang variable sa isang point release. Maaayos ito sa pag-edit ng /etc/yum.repos.d/docker-ce.repo upang gamitin ang bare major number.
Maaaring i-install ang Docker at podman sa iisang server?
Itinuturing ng Docker documentation na conflicting packages ang podman at runc, at sinasabing alisin ang dalawa bago i-install ang Docker Engine. Ang aktuwal na conflict ay ang package na podman-docker. Ito ang nagmamay-ari ng /usr/bin/docker at ginagawang podman command ang bawat command na docker. Patakbuhin ang rpm -qf "$(command -v docker)" upang makita kung aling package ang nagmamay-ari sa path na iyon. Kung nagsisimula sa podman-docker ang output, podman ang sumasagot. Hindi suportado ng Docker ang pagpapanatili ng dalawang engine sa ganitong setup. Kaya sa server na mahalaga ito, pumili ng isa.
Bakit nakakakuha ng permission denied ang container ko sa bind mount?
Naka-enforce bilang default ang SELinux sa Rocky Linux at AlmaLinux. Tumatakbo ang mga container bilang type na container_t at maaari lamang gumamit ng mga file na may label na container_file_t. Kaya maling label ang dala ng directory na ginawa mo, at tinatanggihan ang access anuman ang owner at mode nito. Kumpirmahin ito gamit ang ls -ldZ sa host path at sudo ausearch -m avc -ts recent, na nagpi-print ng avc: denied kasama ang dalawang hindi nagtutugmang context. Idagdag ang :z sa volume argument para sa content na ibinabahagi ng mga container, o :Z para sa content na pribado sa isang container. Huwag kailanman ituro ang :Z sa /home o /usr, dahil recursive ang relabel at masisira nito ang host.
Kailangan ko bang magbukas ng port sa firewalld para ma-publish ang container port?
Hindi, at iyon ang problema. Nire-rewrite ng NAT rule ng Docker ang destination address bago makarating ang packet sa input path ng host, kaya hindi ito naiinspeksyon ng zone rules ng firewalld. Inilalagay din ng Docker ang mga bridge nito sa firewalld zone na tinatawag na docker, na may target na ACCEPT. Maaabot mula sa internet ang container na sinimulan gamit ang -p 8080:80 habang walang pini-print ang sudo firewall-cmd --list-ports. Mag-publish sa isang partikular na address gamit ang -p 127.0.0.1:8080:80 kung host lamang ang dapat makaabot sa service, o magpasok ng filtering rules sa DOCKER-USER chain. Pinoproseso ito ng Docker bago ang sarili nitong accept rules.
Ligtas bang idagdag ang user ko sa docker group?
Nagbibigay ito ng root access. Maaaring magsulat ang miyembro ng docker group sa /var/run/docker.sock, at pagkatapos ay mababasa ng docker run --rm -v /:/host alpine wc -l /host/etc/shadow ang isang root-only file gamit ang account na walang sudo rights. Nakasaad din ang parehong equivalence sa post-install documentation ng Docker. Idagdag lamang ang mga account na pagkakatiwalaan mo na sa sudo, at patuloy na gamitin ang sudo docker para sa shared o service accounts. Ang rootless mode ang alternatibo kapag kailangan mong magpatakbo ng mga container sa ilalim ng unprivileged user. Hiwalay itong install path at hindi isang setting.