برنامه نویسی

1Mindocker #13 – با اقدامات GitHub فشار ، بسازید و dockerize کنید

در مقاله آخر ما در مورد CI/CD صحبت کردیم: اما چگونه می توانیم خط لوله CI/CD را در یک چارچوب بدون دردسر و بسیار ساده قرار دهیم؟

خوب ، دیگر نگو! اقدامات GitHub تمام آنچه را که برای تنظیم یک محیط مناسب برای مرتکب -> ساخت -> dockerize برنامه خود دارید ، داشته باشید.

بیایید شیرجه بزنیم!

تنظیم – GitHub

ما چیزی را به صورت اعطا نمی کنیم ، بنابراین فرض کنیم شما یک حساب کاربری GitHub ندارید و شما فقط می خواهید از ابتدا شروع کنید:

  • به ثبت نام GitHub بروید و در آنجا با ایمیل و رمز عبور خود ثبت نام کنید. از شما نیز خواسته می شود نام کاربری ایجاد کنید
  • فعال کردن 2 عامل احراز هویت (2FA) اختیاری است ، اما توصیه می شود
  • پس از ورود به سیستم و راه اندازی ، وقت آن است که اولین مخزن خود را ایجاد کنید!

برای ایجاد مخزن ، به طور کلی باید روی یک کلیک کنید New یا Create new repository دکمه سبز: از شما خواسته می شود که دید را انتخاب کنید (اگر repo عمومی یا خصوصی باشد) و نام مخزن. من پیشنهاد می کنم که برای این آموزش ، شما ایجاد کنید مخزن عمومی به نام hello-world-github-dockerبشر

تنظیم – برنامه

حال بیایید یک برنامه کاربردی بسازیم: ما از Python ، یک زبان برنامه نویسی همه کاره استفاده می کنیم که می توانید برای بسیاری از موارد استفاده کنید ، از ساخت برنامه ها گرفته تا تجزیه و تحلیل داده ها ، از ایجاد وب سایت تا یادگیری ماشین.

بیایید اول از همه کلون مخزن GitHub (یعنی یک نسخه محلی از آن) با آن git (اگر آن را ندارید ، نحوه نصب آن را در اینجا ببینید)

git clone https://github.com/username/hello-world-docker-github
# Remember to change 'username' with your actual username!
cd hello-world-docker-github/
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و اکنون ، بیایید ویرایش خود را ایجاد و شروع کنیم app.py پرونده (.py پسوند که اسکریپت های پایتون دارند):

touch app.py
code app.py
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در touch دستور پرونده را ایجاد می کند ، در حالی که code دستور پرونده را در کد Visual Studio باز می کند (یک IDE ، محیط توسعه یکپارچه) برای اصلاح آن. بدیهی است که می توانید از IDE های مختلف استفاده کنید: تا زمانی که برای شما کار کند ، هیچ IDE بهتر از دیگری نیست.

به طور کلی ، برنامه “سلام جهان” چاپ می کند “سلام جهان!” در ترمینال ، مانند این:

print("Hello world!")
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اما ما می خواهیم کاری بیشتر انجام دهیم: ما متن سفید وانیلی را در ترمینال خود دوست نداریم ، می خواهیم برخی از 🌈color🌈.

برای انجام این کار ، ما به سادگی باید نصب کنیم termcolor بسته:

pip install termcolor
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون ما فقط آن را وارد اسکریپت خود می کنیم و از آن استفاده می کنیم:

from termcolor import cprint
# cprint stands for "colorer print", and allows us to print colored text

cprint("Hello world!", color="red")
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون متن چاپی قرمز خواهد بود ، اما بیایید حتی برخی از ادویه های دیگر را نیز اضافه کنیم ، و به برنامه اجازه می دهیم یک رنگ تصادفی را برای استفاده در چاپ رشته به ترمینال انتخاب کند:

from termcolor import cprint
import random
# random is the library that allows us to extract random items from a list
colors = ["red", "green", "blue", "magenta", "yellow"]

color = random.choice(colors)

cprint("Hello world!", color=color)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون اسکریپت ما به طور تصادفی یکی از رنگ ها را انتخاب می کند و “سلام جهان!” در آن رنگ 🙂

یادداشت: random یک کتابخانه داخلی در پایتون است ، به این معنی که در زبان قرار می گیرد: به همین دلیل نیازی به نصب آن نداشتیم.

تنظیم – داکر

خوب ، اکنون ما برنامه خود را داریم: چگونه می توانیم آن را dockerize کنیم؟

اولین گزینه ما می تواند نوشتن یک dockerfile ، ساختن تصویری از آن و فشار دادن آن به Docker Hub باشد. این یک راه حل مناسب است ، اما ما باید هر بار که تغییر در برنامه ایجاد می کنیم ، دوباره تصویر را روی دستگاه محلی خود بسازیم و آن را به سمت Docker Hub سوق دهیم. در حالی که برنامه “Hello World” ما نسبتاً کوچک است و این یک بار برای رایانه ما نخواهد بود ، مطمئناً ما می خواهیم با کاربردهای بزرگتر از این کار جلوگیری کنیم.

راه حل دیگر ، همانطور که گفتیم ، نوشتن Dockerfile ، و سپس بارگذاری برنامه ما در GitHub و اجازه دادن به سکو از ساختمان و فشار دادن تصویر به ghcr، یعنی رجیستری کانتینر GitHub، رجیستری که تصاویر Docker ساخته شده در Github (همچنین به عنوان شناخته می شود بسته ها) ذخیره می شوند.

از آنجا که هدف ما بهره برداری از اقدامات GitHub است ، بیایید این کار را انجام دهیم!

اولین کاری که باید انجام دهیم ایجاد یک requirements.txt پرونده ای که تمام وابستگی های لازم را در داخل تصویر Docker ما نصب می کند. در مورد ما ، ما فقط نیاز داریم termcolor، بنابراین ما فقط می توانیم این کار را انجام دهیم:

  • برای ویرایش پرونده ایجاد و باز کنید:
touch requirements.txt
code requirements.txt
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  • نوشتن termcolor بسته در پرونده:
termcolor
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

حالا بیایید ما را بسازیم Dockerfileبشر ما می خواهیم تصویر ما حاوی باشد python، و ما می خواهیم که وابستگی های مورد نیاز را نیز نصب کند ، بنابراین بیایید آن را اینگونه تعریف کنیم:

# Define your python version
ARG PY_VERSION="3.11.9-slim-bookworm"

# Base image
FROM python:${PY_VERSION}

# Define your working directory
WORKDIR /app/
# Copy your local file system into the working directory
COPY ./ /app/

# Install the necessary dependencies
RUN pip cache purge
RUN pip install --no-cache-dir -r requirements.txt

# Run the application as an entrypoint
ENTRYPOINT python3 app.py
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون ساختار پوشه محلی ما به این شکل خواهد بود:

.
|__ app.py
|__ requirements.txt
|__ Dockerfile
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تنها چیزی که ما به آن نیاز داریم پیکربندی یک فایل گردش کار است که باعث ایجاد اقدامات GitHub می شود و به آنها می گوید که تصویر را بسازند و فشار دهند. برای این کار ، ما می توانیم از الگوی پیش ساخته ارائه شده توسط GitHub استفاده کنیم.

ما باید اول از همه پرونده را ایجاد کنیم:

# The file is placed in a special directory, .github/workflows
mkdir -p .github/workflows
touch .github/workflows/docker-publish.yml
code .github/workflows/docker-publish.yml
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

همانطور که مشاهده می کنید ، فایل گردش کار با فرمت YAML است ، یک زبان نشانه گذاری قدرتمند که به شما امکان می دهد تمام مراحل مورد نظر خود را در ساخت مشخص کنید. متن زیر را در پرونده ای که اکنون در حال ویرایش هستید کپی و چسباند:

name: Docker

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
  schedule:
    - cron: '40 8 * * *'
  push:
    branches: [ "main" ]
    # Publish semver tags as releases.
    tags: [ 'v*.*.*' ]
  pull_request:
    branches: [ "main" ]

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as /
  IMAGE_NAME: ${{ github.repository }}


jobs:
  build:

    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      # This is used to complete the identity challenge
      # with sigstore/fulcio when running outside of PRs.
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      # Install the cosign tool except on PR
      # https://github.com/sigstore/cosign-installer
      - name: Install cosign
        if: github.event_name != 'pull_request'
        uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0
        with:
          cosign-release: 'v2.2.4'
      # Set up BuildKit Docker container builder to be able to build
      # multi-platform images and export cache
      # https://github.com/docker/setup-buildx-action
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0

      # Login against a Docker registry except on PR
      # https://github.com/docker/login-action
      - name: Log into registry ${{ env.REGISTRY }}
        if: github.event_name != 'pull_request'
        uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      # Extract metadata (tags, labels) for Docker
      # https://github.com/docker/metadata-action
      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      # Build and push Docker image with Buildx (don't push on PR)
      # https://github.com/docker/build-push-action
      - name: Build and push Docker image
        id: build-and-push
        uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      # Sign the resulting Docker image digest except on PRs.
      # This will only write to the public Rekor transparency log when the Docker
      # repository is public to avoid leaking data.  If you would like to publish
      # transparency data even for private images, pass --force to cosign below.
      # https://github.com/sigstore/cosign
      - name: Sign the published Docker image
        if: ${{ github.event_name != 'pull_request' }}
        env:
          # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
          TAGS: ${{ steps.meta.outputs.tags }}
          DIGEST: ${{ steps.build-and-push.outputs.digest }}
        # This step uses the identity token to provision an ephemeral certificate
        # against the sigstore community Fulcio instance.
        run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون وقت آن است که این گردش کار را آزمایش کنیم!

آزمایش – فشار اول

بیایید اول از همه ، همه تغییرات محلی را به مخزن آنلاین اضافه کنیم ، مرتکب و فشار دهیم:

git add .
git commit -m "first commit"
git branch -M main
git push -u origin main
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

از شما خواسته می شود نام کاربری و رمز عبور GitHub خود را وارد کنید. به عنوان رمز عبور ، شما باید از یک نشانه دسترسی GitHub استفاده کنید ، که می توانید در اینجا ایجاد کنید.

پس از تغییر تغییر ، شما می بینید ، در repo github آنلاین خود ، یک نقطه قهوه ای: این بدان معنی است که گردش کاری که با فشار ما ایجاد کرده ایم اکنون کار می کند و تصویر را می سازد و فشار می آورد. اگر گردش کار موفقیت آمیز باشد ، در انتهای آن یک کنه سبز مشاهده خواهید کرد ، در حالی که اگر شکست بخورد ، یک صلیب سرخ را خواهید دید.

اطمینان حاصل کنید که پس از ایجاد بسته ، آن است عمومی: اگر اینطور نیست ، دید خود را به عموم تغییر دهید ، در غیر این صورت نمی توانید آن را بارگیری کنید.

آزمایش – تلاش برای برنامه ما

همانطور که گفتیم ، تصویر Docker به عنوان بسته زیر بارگذاری می شود ghcr.io؛ سپس می توانیم تصویر را مانند این بکشید و اجرا کنیم:

docker pull ghcr.io/username/hello-world-github-docker:main
docker run -t ghcr.io/username/hello-world-github-docker:main
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اگر Docker می گوید که نمی تواند تصویر را بکشد زیرا شما وارد رجیستری Container GitHub نشده اید ، می توانید به سادگی اجرا کنید:

docker login ghcr.io -u username -p GITHUB-ACCESS-TOKEN
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و این باید جادو را انجام دهد!

وقتی برنامه خود را اجرا کردیم ، باید یک رنگ “سلام جهان!” چاپ شده روی ترمینال.

اصلاح برنامه ما

حال ، بیایید بگوییم که ما می خواهیم به کاربر اجازه دهیم رنگی را که می خواهد “سلام جهان” با آن چاپ کند ، انتخاب کند. ما می توانیم خود را اصلاح کنیم app.py مثل این:

from termcolor import cprint

colors = ["red", "green", "blue", "magenta", "yellow"]

# Tell the user the instructions
print(f"Hello user! What color would you like 'Hello world' to be printed with?\nChoose among: {', '.join(colors)}")

# Take the input from the user
color = input("-->")

# Check if the input is in the available colors: if not, tell the user that it is not available
if color.lower() in colors:
    cprint("Hello world!", color=color)
else:
    print("ERROR! The color you chose is not among the available colors :(")   
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای اصلاح تصویر Docker ، اکنون اضافه کردن ، تعهد و فشار آوردن تغییرات محلی به repo آنلاین کافی است:

git add .
git commit -m "user defined color"
git push origin main
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اگر گردش کار دوباره موفقیت آمیز باشد ، ما باید بتوانیم تصویر جدید را با ویژگی های به روز شده بکشید و اجرا کنیم:

docker pull ghcr.io/username/hello-world-github-docker:main
docker run -it ghcr.io/username/hello-world-github-docker:main
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ما برای این مقاله در اینجا متوقف خواهیم شد ، اما در مورد بعدی ، ما با استفاده از Docker برای استقرار در ابرهای مختلف استفاده خواهیم کرد: با ما همراه باشید و از آن لذت ببرید!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا