חידת דוקר: שינוי הרשאות

23/05/2022

בתיקיה חדשה ניצור 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. הסבר ופיתרון

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, והוא זה שיהיה ממופה לתיקיית העבודה במחשב המארח ויתעדכן אוטומטית עם כל שינוי.