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