• בלוג
  • איך לבנות אוטומטית Docker Image מכל קומיט

איך לבנות אוטומטית Docker Image מכל קומיט

גיטהאב מספקים שני משאבים מופלאים ובחינם - אחד נקרא Actions והשני Packages. יחד הם מאפשרים לנו ליצור Docker Image במאגר פרטי מכל קומיט ובצורה אוטומטית. בואו נראה את זה בפעולה.

1. היתרון של אימג' מכל קומיט

אבל לפני שנגיע להסבר הטכני בואו נדבר על הערך של בניית אימג' אוטומטית מכל קומיט - הוא היכולת לבנות מהר ובצורה מדויקת סביבת פיתוח לכל קומיט.

אם מפתחים צריכים להפעיל build אחרי שמושכים את המאגר, אז כל מפתח שמפעיל build עשוי לקבל תוצאה קצת שונה (בגלל סקריפטים שרצים בזמן בניית האימג'), ועשויים להיתקל בבאגים מוזרים שנובעים מבעיות בבניה. לעומת זאת אם יש לנו בילד אוטומטי בכל קומיט, אז מאוד קל למפתחים להיות בטוחים שאנחנו עובדים בדיוק על אותה גירסה וקל להרים מהר שרת עם גירסה של אימג' לפי קומיט בשביל לשתף עם אנשי מוצר או QA. את הקמת השרת אפשר יהיה אפילו לעשות אוטומטית.

בפוסט זה נראה איך להשתמש ב Github Action כדי לבנות אימג' מ Dockerfile, ואיך להשתמש במאגר אימג'ים (Registry) של Github Packages כדי לאחסן בו כל אימג' שאנחנו בונים מתויג לפי מזהה הקומיט.

2. דרישות קדם - אסימון גישה

לפני שאפשר יהיה לדחוף אימג' אוטומטית ל Registry עלינו לקבל אסימון גישה עם הרשאות דחיפה. בשביל זה ניכנס למסך הזה: https://github.com/settings/tokens/new

נבחר את ההרשאות write:packages ו read:packages, נשמור ונעתיק הצידה את אסימון הגישה שיצרנו.

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

3. מבנה הפרויקט

הפרויקט שאני עובד עליו נקרא express-app ואפשר למצוא אותו בקישור: https://github.com/ynonp/express-app

בתוך תיקיית .github/workflows נמצא קובץ האקשן:

name: 'build'

on:
  push:
    branches:
    - main
  pull_request:

jobs:
  build:
    name: 'Build'
    runs-on: ubuntu-latest
    steps:
      - name: "Build:checkout"
        uses: actions/checkout@v2
      - name: 'Build:dockerimage'
        uses: docker/build-push-action@v1
        with:
          registry: ghcr.io
          username: "ynonp"
          password: ${{ secrets.PAT }}
          repository: ynonp/express-app
          tags: latest,${{github.sha}}

תצטרכו להחליף את שם המשתמש לשם משתמש הגיטהאב שלכם, וגם לשנות את שם הריפוזיטורי למשהו שמתאים לפרויקט שלכם.

בנוסף בתיקייה הראשית של הפרויקט יצרתי Dockerfile עם התוכן הבא:

FROM node:18-alpine
ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production

COPY . .

CMD ["node", "./bin/www"]

עבור פרויקט Node.JS.

4. תוצאה - בניה

וזה הכל. מכאן כל פעם שאני דוחף קוד לפרויקט באופן אוטומטי נבנה Image המתויג לפי ה SHA של הקומיט ועולה לריפוזיטורי פרטי שלי על Github Packages. ה URL של הריפוזיטורי לדוגמה שיצרתי הוא:

https://github.com/users/ynonp/packages/container/package/express-app

ומה שהכי טוב עכשיו זה שאפשר לחשב אוטומטית את שם האימג' לפי ה Hash של הקומיט לדוגמה:

ghcr.io/ynonp/express-app:588d27d0e9640323d6b2554581305cef4100c44f

ולכן פקודה כזאת תפעיל את האימג' שמתאים ל SHA מסוים בדוקר על המכונה שלי:

$ docker run -p 3001:3000 --rm ghcr.io/ynonp/express-app:588d27d0e9640323d6b2554581305cef4100c44f