טיפ דוקר: סדר פעולות ב Dockerfile

14/03/2022

פוסט זה כולל טיפ קצר על Docker. אם אתם רוצים ללמוד יותר לעומק על פיתוח עם Docker, Docker Compose או Kubernetes תשמחו לשמוע שבניתי קורס וידאו מקיף בנושא זה.
למידע נוסף והצטרפות לקורס בקרו בדף קורס Docker כאן באתר.
 

קובץ ה Dockerfile הבא מגדיר בניה של אפליקציית Rails שגם מכילה קוד צד לקוח, שבתורו מתקמפל עם node.js:

FROM ruby:2.7

WORKDIR /app
COPY . .

ENV RAILS_ENV=production
ENV NODE_ENV=production

RUN gem install bundler:2.2.5
RUN sh -c "apt-get update && apt-get install -y nodejs npm"

RUN bundle install

RUN sh -c "cd client; npm install"
RUN "./bin/rails assets:precompile"

CMD ["./bin/rails", "s"]

רואים מה הבעיה כאן?

תוכן עניינים

  1. סדר פעולות ושכבות

1. סדר פעולות ושכבות

הפקודות RUN, COPY ו ADD של דוקר יוצרות כל אחת שיכבה חדשה. ברגע שדוקר מסיים ליצור שכבה הוא שומר אותה ב Cache, וכשמפעילים פעם נוספת build דוקר יוכל להשתמש בעותק השמור - בתנאי שלא היה שינוי בשיכבה או בשכבות שמעליה.

בקוד הדוגמה הפעולה:

COPY . .

יוצרת שיכבה חדשה, אבל זו שיכבה מאוד לא יציבה. כל שינוי הכי קטן בקובץ בתיקיית הפרויקט יגרום ל Cache להיות לא רלוונטי, ולדוקר לזרוק את השיכבה ואת כל השכבות שהוא בנה מעליה, וליצור את הכל מחדש.

זה אומר שעם קובץ Dockerfile כזה אתם תצטרכו לחכות הרבה זמן כל פעם שבונים מחדש את הפרויקט.

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

FROM ruby:2.7

WORKDIR /app

ENV RAILS_ENV=production
ENV NODE_ENV=production

RUN gem install bundler:2.2.5
RUN sh -c "apt-get update && apt-get install -y nodejs npm"

COPY . .
RUN bundle install

RUN sh -c "cd client; npm install"
RUN "./bin/rails assets:precompile"

CMD ["./bin/rails", "s"]

העליתי למעלה את שתי פקודות ה RUN הכלליות יותר (התקנת bundler והתקנת node ו npm), כך שהן נמצאות עכשיו מעל ה COPY. מכאן דוקר יוכל לשמור ב Cache את המכונה אחרי התקנת bundler, node ו npm, ולהתקין רק את הפרויקט שלי כל פעם שמשהו משתנה.