SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-09-05

התקנת Docker על Rocky Linux ועל AlmaLinux: מדריך מלא

למדו להתקין Docker Engine על Rocky Linux ועל AlmaLinux בעזרת dnf. המדריך פותר את בעיות ה-alias של podman ומונע שגיאות הרשאות SELinux ב-bind mounts הנפוצות במערכות RHEL.

התקנת Docker על Rocky Linux ועל AlmaLinux

כדי להתקין את Docker על Rocky Linux או על AlmaLinux, יש להוסיף את מאגר ה-dnf הרשמי של Docker, להתקין את המנוע יחד עם התוסף compose, ולאחר מכן להפעיל את השירות. מדובר בארבע פקודות, והתהליך זהה בשתי ההפצות כיוון ששתיהן מבוססות על Red Hat Enterprise Linux (RHEL) וחולקות את אותו מבנה חבילות. CentOS Stream פועלת באותו אופן. כל מה שמופיע להלן תקף לשתי ההפצות, לכן אם אתם עדיין מתלבטים ביניהן, גורמי ההכרעה הם הבטחת התאימות שכל פרויקט מספק והשאלה האם המעבד הישן שלכם עדיין נתמך.

ההתקנה קצרה, לכן רוב המדריך הזה עוסק בהבדלים בין Enterprise Linux (EL) לבין Ubuntu. ייתכן ש-Podman כבר משתמש בפקודה docker בתמונה שלכם. SELinux חוסם קבצים ב-bind-mount עד שהם מקבלים את התווית (label) המתאימה. Firewalld אינו מסנן פורטים ש-Docker מפרסם, לכן פורט של מכולה עלול להיות חשוף לאינטרנט בעוד ש-firewall-cmd מדווח ששום פורט אינו פתוח.

אל תשתמשו בסקריפט הנוחות של Docker מ-get.docker.com. התיעוד הרשמי של Docker מציין שהוא אינו מומלץ לסביבות ייצור (production). הסקריפט משכתב את הגדרות המאגר שלכם ללא אישור, ולא ניתן להריץ אותו שוב בבטחה לצורך שדרוג. הוספת המאגר באופן ידני מאפשרת ל-dnf upgrade להתייחס ל-Docker כמו לכל חבילה אחרת במערכת. זה גם מכניס את המנוע לטווח הפעולה של dnf-automatic, אם הגדרתם אותו להחלת עדכוני אבטחה מתוזמנים, לכן החליטו מראש אם אתם מעוניינים ש-Docker יתעדכן אוטומטית או שאתם מעדיפים להמתין לחלון תחזוקה. כך או כך, שדרוג מחליף את הקובץ הבינארי המותקן בזמן ש-dockerd הישן ממשיך לרוץ, ו-needs-restarting היא הפקודה שתציג לכם אילו שירותים עדיין מריצים את הקוד שהרגע החלפתם.

האם Podman כבר משיב לפקודת docker?

ההפצות Rocky Linux ו-AlmaLinux כוללות את Podman במאגרים המובנים שלהן, ותמונות VPS רבות מתקינות אותו כברירת מחדל. חלק מהתמונות מרחיקות לכת ומתקינות את podman-docker, אשר מציב סקריפט shell בנתיב /usr/bin/docker הקורא ל-Podman. כתוצאה מכך, כל פקודת docker שתקלידו תריץ את Podman במקום, ומדריך שנכתב עבור Docker יפיק פלט שלא ציפיתם לו.

הסימן הראשון הוא באנר. הסקריפט /usr/bin/docker בודק את קיום הקובץ /etc/containers/nodocker, וכאשר הקובץ חסר, הוא מדפיס שורה אחת לפני הרצת הפקודה:

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

ייתכן שמישהו יצר את הקובץ הזה כדי להשתיק את הבאנר, לכן אל תסתמכו עליו בלבד. שאלו את מסד הנתונים של החבילות איזו חבילה מחזיקה בקובץ הבינארי:

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

תשובה המתחילה ב-podman-docker מעידה על כך ש-Podman הוא המשיב לפקודה. תשובה המתחילה ב-docker-ce-cli מעידה על Docker אמיתי. אם rpm -qf מדווח שאף חבילה אינה מחזיקה בקובץ, סימן שהוא הותקן ידנית; במקרה כזה, קראו את הסקריפט לפני שתסמכו עליו.

Podman מריץ את אותן תמונות OCI ומהווה בחירה סבירה. אם הוא מתאים לכם, עצרו כאן. שניהם מנועי קונטיינרים ל-Linux, לכן אם ההחלטה על הפלטפורמה עדיין פתוחה, כדאי לדעת ש-FreeBSD jails מבודדים סביבת משתמש מלאה במקום להריץ תמונות שכבות שנמשכו מ-registry. אם אתם מעוניינים ב-Docker Engine, הסירו תחילה את החבילות המתנגשות. זו הרשימה ש-Docker מתעדת עבור RHEL:

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

קראו מה dnf מתכנן להסיר לפני שתאשרו. בתמונת VPS נקייה הרשימה קצרה. בשרת שכבר נעשה בו שימוש, הסרת podman עלולה להסיר גם את cockpit-podman או כלי אחר התלוי בו.

שמירה על Podman לצד Docker אפשרית עקרונית: הסירו רק את podman-docker, כדי ששם הפקודה docker יהיה פנוי, ואת runc, שהחבילה containerd.io מחליפה. התיעוד של Docker מתייחס ל-Podman כאל חבילה מתנגשת, לכן תצורה זו אינה נתמכת על ידי Docker. אם ההתקנה עדיין מדווחת על התנגשות, השתמשו ברשימת ההסרה המלאה שלעיל.

הוספת המאגר של Docker באמצעות dnf config-manager

Docker מפיצה חבילות RPM עבור Enterprise Linux בכתובת download.docker.com. קובץ המאגר מצביע על עץ ה-CentOS, שהוא העץ שמולו Rocky Linux ו-AlmaLinux מבצעות רזולוציה. הפניית שרת Rocky למאגר של CentOS נראית כטעות, עד שמבינים כיצד שתי ההפצות צמחו משושלת CentOS לאחר ש-Red Hat הפכה את CentOS ל-Stream בשנת 2020. נכון לאוגוסט 2026, Docker מתעדת מאגר זה עבור CentOS Stream 9 ו-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

גרסה 5 של dnf הסירה את הארגומנט --add-repo, ולכן הפקודה השנייה נכשלת בהפצות חדשות. בדקו איזו גרסה מותקנת אצלכם, ולאחר מכן בחרו את הפקודה המתאימה:

dnf --version

אם הפלט מציג גרסה 5.x, השתמשו בפורמט ה-subcommand במקום:

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

שתי הפקודות כותבות את אותו הקובץ ל-/etc/yum.repos.d/docker-ce.repo. הפורמט השגוי ייכשל עם שגיאת unknown-argument במקום לבצע פעולה שגויה בשקט, כך שלא תפספסו זאת.

קובץ המאגר מגדיר את baseurl לנתיב המכיל את $releasever, ו-dnf מרחיבה משתנה זה מתוך חבילת ה-release שלכם. Rocky Linux ו-AlmaLinux מגדירות אותו למספר הגרסה המרכזי (major version), כלומר 9 ב-EL 9 ו-10 ב-EL 10; זו הסיבה שמאגר CentOS נפתר כראוי בשרת Rocky. אשרו את ההרחבה לפני ההתקנה:

sudo dnf repoinfo docker-ce-stable

קראו את השורה Repo-baseurl. היא אמורה להסתיים ב-/9/x86_64/stable או ב-/10/x86_64/stable. אם ה-release שלכם מגדיר את $releasever לגרסת נקודה כגון 9.6, ה-dnf תדווח על Status code: 404 עבור כתובת ה-URL בעת משיכת המטא-דאטה. תקנו זאת על ידי עריכת /etc/yum.repos.d/docker-ce.repo והחלפת $releasever במספר הגרסה המרכזי בלבד.

התקנת המנוע ותוסף ה-compose

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

חמש חבילות, כאשר כל אחת מבצעת תפקיד אחד. docker-ce הוא ה-daemon, כלומר dockerd. docker-ce-cli הוא פקודת ה-docker שאתם מקלידים. containerd.io הוא ה-runtime של המכולות שבו ה-daemon משתמש. docker-buildx-plugin בונה images. docker-compose-plugin מספק את docker compose כפקודת משנה.

חבילות אלו אינן מתקינות קובץ בינארי עם מקף בשם docker-compose. זה היה Compose v1, שהגיע לסוף חייו ביולי 2023. כל מה שקורא ל-docker-compose עם מקף דורש עדכון ל-docker compose עם רווח.

ההתקנה הראשונה עוצרת כדי לייבא את מפתח החתימה של Docker ומציגה לכם את ה-fingerprint שלו. המפתח מגיע מ-gpgkey=https://download.docker.com/linux/centos/gpg בקובץ ה-repo שהוספתם זה עתה, לכן השוו את ה-fingerprint ש-dnf מציג מול כתובת ה-URL הזו לפני שתאשרו אותו.

כשל אחד מופיע לעיתים קרובות מספיק כדי לציין אותו. אם dnf מדווח ש-containerd.io דורש את container-selinux ושום דבר לא מספק אותו, מאגר ה-AppStream שלכם מושבת. הריצו את dnf repolist וודאו ש-appstream מופיע ברשימה, כיוון ששם container-selinux מופץ ב-EL 9 וב-EL 10.

הפעלת Docker ואימות פעולתו

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

חבילות ה-RPM של Docker משאירות את ה-daemon במצב עצור ומושבת לאחר ההתקנה. זו הסיבה ששלב זה מופיע בדף ה-CentOS של Docker ולא בדף ה-Ubuntu, שבו ה-deb מפעיל את השירות עבורך. אם תדלג על enable, ה-Docker יפעל עד לאתחול הבא, אך לאחר מכן יישאר כבוי ויגרור איתו את כל ה-containers.

הפקודה systemctl status אמורה להציג Active: active (running). ה-container מסוג hello-world אמור להדפיס This message shows that your installation appears to be working correctly. ולצאת. אם במקום זאת מופיעה שגיאת הרשאות ב-/var/run/docker.sock, סימן שדילגת על sudo, אשר מתוקן באמצעות סעיף קבוצת ה-docker להלן.

יש לבדוק את ה-compose plugin בנפרד, כיוון שמדובר בחבילה שונה שעלולה להיות חסרה גם אם ה-engine תקין:

docker compose version

תגובה תקינה נראית כמו Docker Compose version v2.x.x. החזרת השירותים שלך לאחר אתחול היא נושא נפרד מהפעלת ה-daemon, ו-מדיניות restart קובעת האם שירותי Compose יעלו מחדש בעת עליית המערכת.

מדוע bind mount מחזיר שגיאת permission denied?

הפצות Rocky Linux ו-AlmaLinux מריצות כברירת מחדל את SELinux (Security-Enhanced Linux) במצב enforcing. ניתן לאמת זאת באמצעות הפקודה getenforce, שמציגה את Enforcing.

מכולות Docker רצות תחת ה-type של SELinux בשם container_t, וסוג זה רשאי לקרוא ולכתוב רק קבצים המסומנים ב-container_file_t. ספריה שיצרתם במערכת המארחת נושאת את התווית של נתיב האב שלה, שאינה container_file_t. הגישה מהמכולה נחסמת, גם אם הבעלים, הקבוצה והרשאות הגישה נראים תקינים מצד המערכת המארחת. ניתן לשחזר זאת בשלוש פקודות:

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

המכולה תציג את השגיאה הבאה:

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

שתי פקודות יחשפו את הסיבה. ls -ldZ /srv/site מציגה את התווית, שעבור נתיב תחת /srv היא system_u:object_r:var_t:s0 ולא container_file_t. לאחר מכן, sudo ausearch -m avc -ts recent מציגה את רשומת ה-audit של ה-kernel, המכילה את avc: denied { read }, שדה scontext= המציין את container_t, ושדה tcontext= המציין את התווית שראיתם על הספריה. חוסר ההתאמה בין שני השדות הללו הוא הגורם לבעיה.

הפתרון הוא הוספת סיומת לארגומנט ה-volume. Docker תבצע עבורכם את סימון התווית מחדש (relabel) לנתיב:

sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro,z nginx:alpine cat /usr/share/nginx/html/index.html

הסיומת :z באותיות קטנות מסמנת את התוכן כמשותף (shared), כך שמספר מכולות יכולות להשתמש באותה ספריה. הסיומת :Z באותיות גדולות מסמנת את התוכן כפרטי ולא משותף (private), והוא משויך למכולה אחת בלבד; מכולה שנייה שתנסה לקרוא את אותו נתיב תיחסם. השתמשו ב-:z עבור כל נתיב שגם מכולת sidecar או מכולת גיבוי ניגשות אליו. השתמשו ב-:Z עבור ספרית מסד נתונים שנמצאת בבעלות מכולה אחת בלבד.

תיעוד ה-Docker כולל אזהרה שחשוב לחזור עליה, כיוון שה-relabel הוא רקורסיבי. ביצוע bind-mount לספרית מערכת כמו /home או /usr עם :Z "יהפוך את המערכת המארחת לבלתי שמישה, וייתכן שתידרשו לבצע relabel לקבצי המערכת באופן ידני". השתמשו בסיומות אלו רק על ספריות שיצרתם עבור המכולה, לעולם לא על נתיבי מערכת.

ב-Compose הסיומת מתווספת לאותה מחרוזת:

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

ישנן שתי מגבלות שקל להיתקל בהן. הדגל --mount אינו יכול להגדיר תווית SELinux כלל, לכן השתמשו ב--v כאשר אתם זקוקים לכך. volumes בעלי שם (named volumes) אינם זקוקים לסיומת, כיוון ש-Docker מסמנת בעצמה את הספריות שהיא יוצרת תחת /var/lib/docker/volumes.

אל תכבו את SELinux. השתמשו ב-sudo setenforce 0 רק כבדיקה של דקה אחת: אם המכולה עובדת לאחר מכן, הבעיה היא אכן בתווית ו-:z הוא הפתרון. החזירו את המצב לקדמותו עם sudo setenforce 1 מיד לאחר מכן. ב-Enterprise Linux, שגיאת permission denied ב-bind mount נובעת משתי סיבות נפרדות שנראות זהות מתוך המכולה. האחת היא תווית ה-SELinux. השנייה היא בעלות מספרית רגילה של משתמש וקבוצה, וזהו הנושא שמשתני PUID ו-PGID נועדו לפתור. הפקודה ls -lnZ תציג לכם את ההרשאות, הבעלים המספרי והתווית בשורה אחת, כך שתוכלו לדעת מול מה אתם מתמודדים.

מדוע פורט שפורסם נגיש למרות ש-firewalld נראה סגור?

Firewalld הוא ה-firewall המוגדר כברירת מחדל ב-Rocky Linux וב-AlmaLinux. בדקו שהוא רץ באמצעות sudo systemctl is-active firewalld. אם טרם הגדרתם אותו בשרת זה, פתיחת SSH ופורט אינטרנט עם firewalld היא הצעד הראשון, כיוון שההפתעה להלן מובנת רק לאחר שיש לכם סט חוקי zone פעיל להשוואה. כעת, פרסמו פורט ובדקו מה firewalld מזהה כפתוח:

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

firewall-cmd מדפיס שורה ריקה. ממכונה אחרת, curl -I http://YOUR_SERVER_IP:8080/ מחזיר HTTP/1.1 200 OK. הפורט פתוח לאינטרנט וה-firewall שלכם לא מדווח על דבר.

הסיבה היא הנתיב שהחבילה עוברת. חוקי ה-zone של firewalld מסננים תעבורה הממוענת למארח עצמו. פורט שפורסם אינו ממוען למארח: Docker מתקין חוק destination NAT (תרגום כתובות רשת) שמשכתב את היעד לכתובת המכולה לפני שהחבילה מגיעה לנתיב ה-input של המארח, לכן ה-kernel מעביר (forward) את החבילה במקום למסור אותה מקומית. לאחר מכן, Docker מציב את ממשקי ה-bridge שלו ב-zone של firewalld שנקרא docker שהיעד (target) שלו הוא ACCEPT, ומוסיף מדיניות העברה בשם docker-forwarding המאפשרת העברה מכל zone לתוך ה-zone של docker. חוקי ה-zone שלכם לעולם לא רואים את החבילה.

הפתרון הנקי ביותר אינו דורש חוק firewall. קשרו את צד המארח של הפרסום ל-loopback והציבו reverse proxy לפניו:

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 המקומי מחזיר HTTP/1.1 200 OK ואותה בקשה ממכונה אחרת כבר לא מתחברת. כל דבר ללא כתובת מארח בארגומנט -p מפורסם בכל הממשקים, לכן התייחסו ל--p 8080:80 חשוף כהחלטה לחשוף את השירות לציבור.

כאשר אתם זקוקים לשירות שיהיה נגיש מכתובות מסוימות ולא מאחרות, Docker שומר עבורכם שרשרת (chain). DOCKER-USER מעובד לפני חוקי ה-accept של Docker, לכן חוק שתציבו שם ישרוד אתחול של Docker ושכתוב של השרשראות שלו:

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

קחו את שם הממשק מ-ip route show default במקום להניח eth0, כיוון שתמונות EL עדכניות משתמשות בשמות כמו enp1s0 או ens3. ב-Rocky וב-AlmaLinux הפקודה iptables היא שכבת תאימות מעל nftables, והשרשראות של Docker גלויות דרכה. חוקים שנוספו בדרך זו נעלמים לאחר reboot אלא אם תשמרו אותם, לכן כתבו אותם לתוך יחידת systemd ברגע שאתם מרוצים מהם.

Docker Engine 28.0, ששוחרר ב-2025, סגר פרצה סמוכה: גישה ישירה ומנותבת לפורטים של מכולות שמעולם לא פורסמו חסומה כעת בשרשרת DOCKER. שינוי זה אינו משפיע על פורטים שפורסמו, לכן כל האמור לעיל עדיין תקף בגרסאות נוכחיות. כדאי לאמץ הרגל תפעולי אחד: לאחר כל sudo firewall-cmd --reload, בדקו שוב פורט שפורסם. אם הוא הפסיק להגיב, sudo systemctl restart docker מתקין מחדש את החוקים של Docker.

מנהלי מערכות Ubuntu נתקלים באותו קיר דרך כלי אחר, וזו הסיבה לכך שפורטי Docker שפורסמו מתעלמים מחוקי ufw. נתיב ה-NAT הוא הסיבה בשני המקרים. רק ה-firewall שלפניו משתנה.

הוספת משתמש שאינו root לקבוצת docker

הקלדת sudo לפני כל פקודת docker הופכת למעיקה, והקבוצה docker מבטלת את הצורך בכך:

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

usermod -aG עורך את /etc/group, אך ה-shell הנוכחי שלך כבר מחזיק ברשימת הקבוצות שלו, לכן השינוי לא יחול עד שתפתח shell חדש. newgrp docker מפעיל shell עם הקבוצה משויכת כך שתוכל לבדוק זאת מיד. חיבורי SSH חדשים יזהו זאת באופן אוטומטי.

היה ברור לגבי ההרשאות שקבוצה זו מעניקה. חברות בקבוצה מעניקה גישת כתיבה ל-/var/run/docker.sock, וכל גורם שיכול לתקשר עם ה-socket הזה יכול לבקש מה-daemon להפעיל מכולה שמבצעת mount למערכת הקבצים של המארח. פקודה אחת מדגימה מה המשמעות של זה:

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

פקודה זו קוראת קובץ שרק root יכול לקרוא, מחשבון ללא הרשאות sudo. תיעוד ה-post-install של Docker עצמו מציין זאת: הקבוצה docker מעניקה הרשאות השקולות ל-root. הוסף חשבון לקבוצה זו רק אם היית נותן לאותו חשבון גם sudo. אם אתה מגדיר חשבונות בשרת חדש, החלט על כך כחלק מיתר תהליך ה-הגדרת משתמשים בעלי הרשאות מינימליות ב-VPS ולא בדיעבד.

Docker מציעה גם מצב rootless המריץ את ה-daemon כמשתמש ללא הרשאות מיוחדות. זהו נתיב התקנה נפרד והוא משנה את אופן הפעולה של מנהלי האחסון ושל פורטים מתחת ל-1024, לכן תכנן זאת כפרויקט עצמאי ולא כדגל (flag) שמוסיפים מאוחר יותר.

צעדים הבאים

כעת ברשותך המנוע, תוסף ה-compose, שירות ששורד אתחול, ושלושת המאפיינים הספציפיים ל-EL שתועדו לעיל. הצעד הבא הוא compose.yaml לכל שירות, והמאמר מבנה קובץ Compose סוקר את פורמט הקובץ ואת הפקודות המפעילות אותו. אם זהו מארח המכולות הראשון שלך, המדריך הרצת Docker על גבי VPS מכסה את שאלות הגודל, האחסון ותחזוקת האימג'ים שהמדריך הנוכחי אינו כולל.

FAQ

האם ה-repository של Docker עבור CentOS עובד על Rocky Linux ועל AlmaLinux?

כן. יש להוסיף את https://download.docker.com/linux/centos/docker-ce.repo באמצעות dnf config-manager. ה-baseurl בקובץ זה מכיל את $releasever, ו-Rocky Linux ו-AlmaLinux מרחיבות אותו למספר הגרסה המרכזי. לכן, שרת EL 9 יפנה לעץ של CentOS 9, ושרת EL 10 יפנה לעץ של CentOS 10. ניתן לאמת את ההרחבה באמצעות sudo dnf repoinfo docker-ce-stable ולקרוא את השורה Repo-baseurl. שגיאת Status code: 404 בעת משיכת מטא-דאטה על ידי dnf מעידה על כך שהמשתנה הורחב לגרסת נקודה (point release); עריכת /etc/yum.repos.d/docker-ce.repo לשימוש במספר הגרסה המרכזי בלבד פותרת זאת.

האם ניתן להתקין Docker ו-podman על אותו שרת?

התיעוד של Docker מציין את podman ו-runc כחבילות מתנגשות ומנחה להסיר את שתיהן לפני התקנת Docker Engine. ההתנגשות המעשית היא בחבילת podman-docker, אשר מחזיקה ב-/usr/bin/docker והופכת כל פקודת docker לפקודת podman. הרצו את rpm -qf "$(command -v docker)" כדי לראות איזו חבילה מחזיקה בנתיב זה. אם הפלט מתחיל ב-podman-docker, סימן ש-podman משיב. החזקת שני המנועים אינה תצורה ש-Docker תומכת בה, לכן בשרת שחשוב לכם, בחרו באחד מהם.

מדוע אני מקבל שגיאת permission denied ב-bind mount של מכולה?

SELinux מופעל כברירת מחדל ב-Rocky Linux וב-AlmaLinux. מכולות רצות תחת הסוג container_t ורשאיות לגשת רק לקבצים המסומנים ב-container_file_t. לכן, תיקייה שיצרתם נושאת תווית שגויה והגישה נחסמת ללא קשר לבעלים או להרשאות הקובץ. אשרו זאת באמצעות ls -ldZ על נתיב המארח ו-sudo ausearch -m avc -ts recent, שמדפיס avc: denied עם שני ההקשרים שאינם תואמים. הוסיפו את :z לארגומנט ה-volume עבור תוכן משותף בין מכולות, או את :Z עבור תוכן פרטי למכולה אחת. לעולם אל תפנו את :Z אל /home או /usr, כיוון שהסימון מחדש הוא רקורסיבי וישבש את המערכת המארחת.

האם עלי לפתוח פורט ב-firewalld כדי לפרסם פורט של מכולה?

לא, וזו בדיוק הבעיה. חוק ה-NAT של Docker משכתב את כתובת היעד לפני שהחבילה מגיעה לנתיב ה-input של המארח, ולכן חוקי ה-zone של firewalld לעולם לא בודקים אותה. Docker גם מציבה את ה-bridges שלה בתוך zone של firewalld בשם docker עם יעד ACCEPT. מכולה שהופעלה עם -p 8080:80 נגישה מהאינטרנט בעוד ש-sudo firewall-cmd --list-ports לא מדפיס דבר. פרסמו לכתובת ספציפית עם -p 127.0.0.1:8080:80 כאשר רק המארח אמור לגשת לשירות, או הכניסו חוקי סינון לשרשרת DOCKER-USER, ש-Docker מעבדת לפני חוקי ה-accept שלה.

האם הוספת המשתמש שלי לקבוצת docker היא בטוחה?

זה מעניק הרשאות root. חבר בקבוצת docker יכול לכתוב ל-/var/run/docker.sock, ו-docker run --rm -v /:/host alpine wc -l /host/etc/shadow לאחר מכן קורא קובץ שנגיש ל-root בלבד מחשבון ללא הרשאות sudo. התיעוד שלאחר ההתקנה של Docker מציין את אותה שקילות. הוסיפו רק חשבונות שאתם כבר סומכים עליהם עם sudo, והמשיכו להשתמש ב-sudo docker עבור חשבונות משותפים או חשבונות שירות. מצב Rootless הוא החלופה כאשר נדרשות מכולות תחת משתמש ללא הרשאות, וזהו נתיב התקנה נפרד ולא רק הגדרה.