أتمتة نشر التحديثات إلى Digitalocean باستخدام Github Actions

نشر في 16 يناير 2022

مرحبًا،
سأفترض هنا أن لديك خادم على Digitalocean و تريد نشر تحديثات تطبيقك إليه مباشرة وبشكل مستمر (Continuous Deployment) وهذا ما سنقوم هنا بإعداده سويًا باستخدام Github Actions

  1. قم بسحب كود تطبيقك إلى الخادم للمرة الأولى يدويا باستخدام git clone وتشغيله
  2. قم بإضافة ملف production_deploy.yml إلى المجلد الرئيسي لمشروعك تحت المسار التالي:
.github/workflows/production_deploy.yml
  1. قم بلصق الكود التالي في الملف
name: Production Deployment
on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Deploy your_website over ssh
        uses: appleboy/ssh-action@master
        with:
          host: your_droplet_ip_address
          username: your_username
          key: ${{ secrets.DEPLOYMENT_SECRET }}
          port: 22
          script: |
            cd /var/www/your_app_folder 
            php artisan down
            git fetch origin main
            git reset --hard origin/main
            composer install --optimize-autoloader --no-dev
            php artisan cache:clear
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache
            php artisan queue:restart
            php artisan up
  1. قم بالتغييرات التالية على الكود

    • استبدل your_droplet_ip_address بعنوان ip لخادمك على ديجيتال أوشن
    • استبدل your_username باسم المستخدم الذي تريد للكود أن يستخدمه للوصول إلى الخادم
    • استبدل /var/www/your_app_folder بالمسار الذي يحوي تطبيقك

يعمل هذا الكود كالتالي:

عند نشر أي تحديث إلى فرع (main) في مستودع جيتهاب لتطبيقك، يتم الوصول إلى خادمك عبر ssh وتنفيذ الأوامر في جزء script من الكود بالترتيب

يمكنك التعديل على الكود لاستخدام الفرع (branch) الذي يناسبك أو يمكنك استخدام on: workflow_dispatch لجعل الكود يعمل يدويًا كما يمكنك الرجوع للقائمة الكاملة للأحداث التي يستجيب لها Github Action من هنا

يقوم الكود هنا بتنفيذ أوامر لنشر التحديثات لتطبيق يستخدم Laravel تحديدًا لكن يمكنك التعديل على هذه الأوامر بما يناسبك ويناسب تطبيقك

  1. من سطر الأوامر في حاسوبك أو خادمك قم بتكوين مفتاح ssh باستخدام الأمر التالي
ssh-keygen -f ~/.ssh/github_action

إذا كنت تستخدم windows ستحتاج لاستخدام برنامج مثل PuTTY لتكوين مفتاح ssh

  1. قم بنسخ المفتاح المفتاح السري الموجود في المسار
~/.ssh/github_action

وإضافته إلى مستودع جيتهاب الخاص بك من Settings > Secrets and variables > Actions تحت اسم DEPLOYMENT_SECRET

  1. قم بنسخ المفتاح العمومي الموجود في المسار
~/.ssh/github_action.pub

وإضافته إلى ملف authorized_keys الموجود على خادمك في المسار التالي -إذا لم يكن الملف موجودًا قم بإنشائه-

~/.ssh/authorized_keys

الآن قم بتجربة عمل (push) إلى فرع (main) ويجب أن ترى Github Action يعمل تلقائيًا ليتم نشر التحديثات بشكل صحيح بإذن الله.

نقطة إضافية: يمكن استخدام نسخة معدلة من الكود أعلاه ل (Zero downtime) غير متأكد إذا كانت لها أي آثار جانبية سيئة لكنها تعمل معي بشكل جيد

name: Production Deployment
on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Deploy your_website over ssh
        uses: appleboy/ssh-action@master
        with:
          host: your_droplet_ip_address
          username: your_username
          key: ${{ secrets.DEPLOYMENT_SECRET }}
          port: 22
          script: |
            cd /var/www
            git clone your_github_repo ./your_app_folder-new
            cp ./your_app_folder/.env ./your_app_folder-new
            cd your_app_folder-new
            composer install --optimize-autoloader --no-dev
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache
            php artisan queue:restart
            cd /var/www
            if test -d ./your_app_folder-old; then rm -rf ./your_app_folder-old; fi
            mv ./your_app_folder ./your_app_folder-old && mv ./your_app_folder-new ./your_app_folder

يقوم هذا الكود بعمل نسخة جديدة كليًا من التطبيق في مجلد جديد ومن ثم استبدال المجلد الجديد بالقديم.

عند استخدام هذه النسخة من الكود قد تواجهك مشكلة مع الصلاحيات للوصول إلى الملفات والمجلدات لكن سيتوجب عليك التعامل معها بنفسك بما يتناسب مع خادمك وتطبيقك، حظًا موفقًا ;)

أرجو أن يكون المقال مفيدًا وإذا وجدت أية أخطاء أو كانت لديك تحسينات رجاء أخبرني عبر البريد الإلكتروني أو عبر تويتر