חידת דוקר: שינוי הרשאות
בתיקיה חדשה ניצור 3 קבצים. הראשון הוא Dockerfile:
FROM ubuntu:22.04
WORKDIR /app
COPY . .
RUN chmod +x /app/startup.sh
CMD ["/app/startup.sh"]
השני נקרא startup.sh
ומכיל את התוכן הבא:
#!/bin/bash
echo Hello World
והשלישי docker-compose.yml
עם התוכן הבא:
version: "3.9"
services:
app:
build: .
volumes:
- .:/app
אני מפעיל:
$ docker compose build
$ docker compose run
ומקבל את השגיאה:
[+] Running 1/1
⠿ Container chmod-in-run-app-1 Recreated 0.2s
Attaching to chmod-in-run-app-1
Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/app/startup.sh": permission denied: unknown
מה קרה שם? איך נתקן?
1. הסבר ופיתרון
קל לראות שהבעיה היא שלקובץ startup.sh
אין הרשאת הרצה, אבל מעניין להבין איך זה קרה מאחר וה Dockerfile כולל את השורה:
RUN chmod +x /app/startup.sh
ולתעלומה הפעם יש הסבר פשוט - ה Dockerfile יצר אימג', העתיק את הקובץ startup.sh לתוך האימג' ושינה באימג' את הרשאות ההרצה. אבל אז בא ה docker-compose.yml והחליט למפות את תיקיית העבודה הנוכחית בתור volume ל /app
. מיפוי זה דרס את הקובץ startup.sh
עם הרשאות ההרצה והסתיר אותו באמצעות הקובץ startup.sh
שקיים כבר בתיקיה ושאינו כולל הרשאות הרצה.
ואחרי שמבינים את הבעיה הפיתרון הוא ברור - במקום להעתיק את startup.sh לתוך תיקיית /app
שם הוא יוסתר, אני מעתיק אותו לתיקיה אחרת בזמן יצירת האימג', כלומר משנה את ה Dockerfile לתוכן הבא:
FROM ubuntu:22.04
WORKDIR /app
COPY . .
COPY ./startup.sh /usr/local/bin/startup.sh
RUN chmod +x /usr/local/bin/startup.sh
CMD ["/usr/local/bin/startup.sh"]
עכשיו רגע רגע יגידו הקוראים הערניים - קלקלת הכל. קודם היתה לך מערכת (לא עובדת, נכון, אבל מערכת) שבה כשאני משנה את startup.sh בתיקיה על המחשב המארח אני לא צריך לבנות מחדש את האימג' כדי לראות את השינוי, ואילו עכשיו חייבים להריץ build מחדש כל פעם שמשנים את startup.sh. אם זאת בעיה גם עבורכם כל מה שצריך זה לפצל את הסקריפט startup.sh לשניים - חלק אחד שלו ישב ב /usr/local/bin
, יוגדר בתור ה CMD של האימג', ישנה את ההרשאות ויריץ את /app/startup.sh
והחלק השני, הוא /app/startup.sh
, והוא זה שיהיה ממופה לתיקיית העבודה במחשב המארח ויתעדכן אוטומטית עם כל שינוי.