پروژه مون آمادست و میخوایم بفرستیمش روی سرور. چه روشهایی داریم؟
جدا از اینکه کدوم روشو در پیش بگیریم ما به یه CI/CD نیاز داریم که وقتی تغییری توی کدمون میدیم و روی git می فرستیم فرایند پول شدن پروژه روی سرور و اجرای دستوراتی که باید خودکار انجام شه.
خوب چطوری این automation رو انجام بدیم؟
من هر چه دیدم دور و برم بچه های DevOps کار چنین روشی رو رفتن
همینطور که می بینین ما به منابعی با بیش از ۴ کور CPU و ۵ گیگ رم و بیش از ۷ روز کاری زمان نیاز داریم. آیا این برای همه پروژه ها منطقیه؟
اگر شما یه دولوپر فول استک هستین و دوست دارین تمام کاراتونو خودتون انجام بدین، از طرفی میخواین پروژه تون هزینه پایینی داشته باشه نیازه برین سراغ ....
GitHub Actions
گیت هاب چند سالیه که امکان ساخت ریپو خصوصی رو فراهم کرده، دیگه هم مشکلی با ایرانی بودن نداره. پس اول از همه بهتره بریم سراغ گیت هاب. اینطوری هم پروژه های خصوصیمون و هم عمومی یک جا خواهد بود.
از طرفی ابزاری معرفی کرده به نام GitHub Actions که به شما کمک میده بعد از پوش/پول هر برنچ دلخواه عملیاتی که شما میخواین انجام شه.
چطوری اکشن برای گیت هاب بنویسیم؟
ت
توی گیت هاب یه سر برگ به نام Actions هست و اونجا میتونین از روی نمونه ها یا داکیومنت کامل پیش برین. اما اینجا من میخوام در یک زمان کوتاه یه روش ساده برای انجام کارتون رو یاد بگیرین. پس بریم:
۱. توی ریپوزیتون یه پوشه به نام .github بسازین و درون اون یه پوشه دیگه به نام workflows می سازین. داخل این پوشه قراره تنظیمات اکشن رو بسازیم
۲. اینجا میتونین یک یا چند فایل با پسوند yml بسازین و اکشن ها رو اونجا بنویسین. من دو تا فایل ساختم
۳. خوب حالا بریم برای نوشتن فایل اکشن ( که بهش workflow گفته میشه )
name: Main Deploy
یه اسم برای ورک فلو تون انتخاب کنین. این اسم رو توی صفحه اکشن ها در آینده می بینین. من باز اسم محیط پروداکشن و تست رو متفاوت قرار دادم.
name: Main Deploy
on:
push:
branches: [ "main" ]
خوب در ادامه event ای رو که در ازای اتفاق افتادنش میخوایم این ورک فلو اجرا بشه رو مشخص کردیم. همینطور که می بینین مشخص شده که در طی پوش به برنچ main اجرا بشه.
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
خوب حالا برای این ورک فلو میتونین چندین جاب تعریف کنیم که همزمان اجرا بشن. ما در اینجا یه جاب تعریف می کنیم. در ابتدای امر برای اون جاب اسمی انتخاب می کنیم ( api-main ) اسمیه که من برای جاب گذاشتم.
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
runs-on: ubuntu-latest
خوب runs-on چی میگه؟ ببینید گیت هاب برای اجرای اکشن ها یه سری رانر خودش داره و اکشنی که شما تعریف می کنین رو توی اون محیط اجرا میکنه. به عنوان مثال من اینجا مشخص کردم که روی رانری که ubuntu نسخه آخر رو داره اجراش کن.
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
runs-on: ubuntu-latest
steps:
- name: Connect to Server & Push Update
خوب حالا این جاب api-main یه سری مراحل باید داشته باشه دیگه. ما برای هر مرحله اسمی میتونیم بزاریم که حین اجرای اکشن توی گیت هاب مراحل لاگ انداخته میشه و اگر هر عملی دچار مشکل بشه متوجهش میشین. به عنوان مثال شکل زیر
- name: Go to Project Folder run: sudo cd /home/project - name: Make new Folder run: sudo mkdir test
اینجا دو مرحله تعریف شده. ( توجه کنین به تو رفتگی ها indent - این فایل Yaml هست و تو رفتگی ها بسیار مهمه)
خوب برگردیم به مثال خودمون:
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
runs-on: ubuntu-latest
steps:
- name: Connect to Server & Push Update
uses: appleboy/ssh-action@master
من اینجا میخوام بصورت SSH به سرور خودم وصل شم و دستورات دلخواهم رو انجام بدم. ما میتونیم یا مثل مثال بالا از عبارت run استفاده کنیم و یه دستوری رو اجرا کنیم یا از عبارت uses استفاده کنیم. اما این uses چی میگه؟
شما ممکنه برای اتصال به سرور و نقطه مقصد نیاز به یه سری نرم افزار نصب شده و موارد این چنینی داشته باشین. طبعا اون نرم افزار روی رانر گیت هاب نصب نیست. پس شما اینجا توی uses یک ریپوزیتوری رو مشخص میکنین ( طبعا توی خود گیت هاب باید باشه ) که توی اون ریپوزیتوری فایل docker ای نوشته شده برای ساپورت نیاز شما. مثلا یه ریپوزیتوری برای اتصال به AWS خواهد بود. یکی دیگه برای Azure و ...
از طریق مثالهای خود گیت هاب میتونین با موارد مختلف آشنا شین. اما یه ریپوزیتوری ک من میخواستم و توی گیت هاب ندیدمش. اتصال ssh و انجام دستورات. ریپوزیتوری appleboy/ssh-action برای این نیاز هست. پس ما در اینجا به همین دلیل uses رو با مقدار این ریپو مشخص کردیم.
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
runs-on: ubuntu-latest
steps:
- name: Connect to Server & Push Update
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
port: ${{ secrets.PORT }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
خوب این ریپو طوری نوشته شده که نیاز داره یه سری مقادیر رو براش مشخص کنین. پس از عبارت with استفاده می کنیم و با تو رفتگی بیشتر داخلش موارد فوق رو مشخص می کنیم، مثلا اینطوری
host: 10.25.31.26
اما چرا ما اینطوری نوشتیمش:
host: ${{ secrets.HOST }}
طبعا شما نمیخواین کسی که به ریپوی شما دسترسی داره ( مثلا یکی از برنامه نویسها ) یا حتی ریپو عمومی باشه بتونه این فایل رو بخونه و اطلاعات سرور رو شما رو متوجه بشه. پس از عبارت ${{ secrets.HOST }} استفاده کردیم تا این مقدار رو جای دیگه تعریف کنیم. اما اونجا کجاست؟
توی بخش settings همین پروژه توی بخش secrets and variables یه زیر بخش به نام actions هست. همونطور که توی عکس مشخصه من مقادیر رو وارد کردم. ( اگر حتی کسی بیاد و ویرایش رو بزنه مقدار فعلی رو نمیتونه ببینه)
خوب حالا اون داکری که ساخته میشه تا ssh بزنه میتونه به سرور ما وصل شه. اما با یک نکته. ما بایستی کلید خصوصی ssh سرور مقصدمون رو اینجا وارد کنیم. خوب چطوری اونو بدست میاریم؟
توی سرور خودتون این دستور رو اجرا کنین
ssh-keygen -t rsa -b 4096 -C "mreza_golestan@live.com"
بلافاصله سوالی پرسیده میشه که پیشنهاد میکنم در جوابش مقدار github-actions رو وارد کنین. تا کلیدی که ساخته میشه مجزا باشه و با همین نام. حالا دستور زیر رو اجرا کنین
sudo cat ~/.ssh/github-actions
با این دستور ما مقدار داخل فایل کلید خصوصی github-actions رو که درون پوشه .ssh ساخته شده خواهیم دید. این مقدار رو کپی کنین و داخل مقدار SSH_PRIVATE_KEY گیت هاب بزارین
name: Main Deploy
on:
push:
branches: [ "main" ]
jobs:
api-main:
runs-on: ubuntu-latest
steps:
- name: Connect to Server & Push Update
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
port: ${{ secrets.PORT }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /home/testapi
git reset --hard && git pull origin master
composer dump-autoload
composer update
php artisan storage:link
php artisan migrate
php artisan optimize
حالا در ادامه داخل عبارت script دستورات دلخواهتون رو قرار بدین.
نمونه مثالی که من آوردم برای اجرای لاراول هست. یه توضیحی درباره اش میدم شاید کمک کننده باشه:
طبق تجربه خود من در کمتر از یک دقیقه نسخه جدید کد شما روی سرور با موفقیت قرار میگیره.
یه نکته: گیت هاب اکشن تا ۲۰۰۰ دقیقه اجرا در ماه رایگانه. که حدود ۲ هزار پوش میشه. یعنی بیش از ۶۶ تا پوش در روز. ک بعید میدونم این تعداد پوش انجام بدین در روز. اما اگر هم احیانا براتون کم باشه. هر دقیقه ۰.۰۰۸ دلار هزینه داره یعنی اگر ۱۰۰۰ دقیقه اضافه تر هم استفاده کنین فقط ۸ دلار نیازه بپردازین.
طبق تجربه من یه تیم ۱۰ نفره هم عموما به این محدودیت ۲۰۰۰ دقیقه نمیرسه
امیدوارم این مطلب براتون مفید باشه. خوشحال میشم نظر بدین