برنامه نویسی

استقرار یک برنامه MERN در AWS Elastic Beanstalk با CI/CD

در مقاله قبلی «استقرار خودکار برنامه MERN با GitHub Actions CI/CD»، تا فشار دادن تصاویر به هاب داکر یاد گرفتیم. تا اینجا شما کار بسیار خوبی انجام داده اید! اما این کافی نیست. ما اکنون به سروری نیاز داریم که کانتینرهای ما را 24 ساعت شبانه روز و هفت روز هفته اجرا کند و برای هر کسی که به اینترنت متصل است قابل دسترسی باشد. راه اندازی سرور خود ایده خوبی نیست 😅. بنابراین ما باید یک سرور اجاره کنیم. در این مقاله خواهید آموخت که چه کسی سرور اجاره ای را به ما می دهد و چگونه آن را راه اندازی کنیم.

بیا شروع کنیم

پیش نیازها

  • اگر آموزش های قبلی این مجموعه را دنبال نکرده اید، کد منبع را از اینجا دریافت کنید.
  • مقالات قبلی این مجموعه را بخوانید تا دچار سردرگمی نشوید.
  • حساب AWS.

  • تمام سرویس‌های AWS که در این آموزش استفاده می‌کنیم رایگان هستند اما برای ایجاد حساب کاربری به کارت اعتباری/دبیت نیاز دارید.

قبل از ادامه، توجه داشته باشید که برنامه بهره وری فوق العاده ساده ما به AWS نیاز ندارد. این فقط برای اهداف یادگیری است.

میم بیش از حد مهندسی aws

⚠️ هشدار: فراموش نکنید که به محض اتمام این آموزش، هر نمونه و محیط در حال اجرا را خاموش کنید تا از دریافت صورتحساب جلوگیری کنید.

AWS چیست؟

همانطور که در ابتدا ذکر کردم، ما به شخصی نیاز داریم که به ما اجازه دهد سرور اجاره کنیم و AWS در مورد آن است. نه از نظر فیزیکی مانند یک اتاق و دسته‌ای از جعبه‌ها، اما در فضای ابری به این معنی است که می‌توانید سرورها را از هر نقطه‌ای در جهان اجاره کنید.

اگر سرورهای خود را به صورت فیزیکی راه اندازی کنید اینگونه به نظر می رسد 😂:

مدیریت میم سرورهای خود

اگر زیر یک سنگ زندگی نکرده اید، احتمالاً نام AWS را شنیده اید. مخفف آن است آمرد دبلیوeb اسخدمات AWS (توسط آمازون) طیف گسترده ای از خدمات رایانش ابری، مانند محاسبات، ذخیره سازی، پایگاه داده، تجزیه و تحلیل، یادگیری ماشینی، شبکه، موبایل، ابزارهای توسعه دهنده، امنیت و برنامه های کاربردی سازمانی را ارائه می دهد. برای همه نیازهای شما، نیازی به راه اندازی سرورهای خود را از بین می برد. این یک زیرساخت انعطاف‌پذیر و مقیاس‌پذیر را فراهم می‌کند که می‌تواند برای نیازهای منحصربه‌فرد هر کاربر تنظیم شود، و به طور گسترده‌ای به عنوان یکی از پلتفرم‌های ابری پیشرو در دسترس امروزی در نظر گرفته می‌شود. Google Cloud (توسط گوگل) و Azure (توسط مایکروسافت) هر دو رقبای اصلی AWS هستند.

زمان بزرگ مغز 💡: اگر از ابتدا دنبال می‌کنید، در اولین مقاله «بیایید یک برنامه وب MERN را با پشته کامل بسازیم و مستقر کنیم»، برنامه frontend خود را در Netlify و بک‌اند را در Heroku مستقر کردیم. اینها خوب هستند اما اکثر شرکت ها به IaaS (زیرساخت به عنوان سرور) از PaaS (پلتفرم به عنوان سرور) نیاز دارند.

زیرساخت به عنوان یک سرویس (IaaS) در مقابل پلت فرم به عنوان یک سرویس (PaaS)

این تصویر به وضوح تفاوت بین Iaas و PaaS را نشان می دهد:

IaaS در مقابل PaaS

راه اندازی NGINX

NGINX یک وب سرور محبوب است که اغلب به عنوان متعادل کننده بار، پروکسی معکوس و کش HTTP استفاده می شود. آن را یک کنترل کننده ترافیک در نظر بگیرید که ترافیک را در چندین سرور بر اساس میزان اشغال یک سرور مدیریت می کند.

به عنوان یک پروکسی معکوس، NGINX به عنوان یک رابط بین مشتری و سرور عمل می کند. هنگامی که شما (کلاینت) درخواستی را به سرور ارسال می کنید، از طریق پروکسی معکوس و سپس به وب سرور هدایت می شود. این پراکسی معکوس از چند جهت مفید است: می‌تواند درخواست‌ها را در چندین سرور توزیع کند، محتوای درخواستی مکرر را حافظه پنهان کند، زمان پاسخ را کاهش دهد و در برابر درخواست‌های مخرب محافظت کند.

اگر می‌خواهید درباره NGINX بیشتر بدانید، توصیه می‌کنم «راهنمای NGINX» نوشته فرهان حسن چاودری را در freeCodeCamp بخوانید.

باشه! چرا ما اهمیت می دهیم؟ به جای استقرار فرانت اند و باطن به طور جداگانه، می توانیم به سادگی از یک متعادل کننده بار مانند NGINX استفاده کنیم تا هر دو فرانت اند و باطن را در یک وب سرور ترکیب کنیم، که سپس می تواند درخواست های دریافتی را بر اساس نوع درخواست و بار سرور به سرور مناسب توزیع کند. این فرآیند استقرار را ساده می کند و به اطمینان از عملکرد بهتر و مقیاس پذیری برنامه کمک می کند.

nginx

پیکربندی NGINX

پروژه را در ویرایشگر کد خود باز کنید. در root یک پوشه به نام ایجاد کنید nginx.

در آن پوشه، یک فایل به نام ایجاد کنید nginx.conf و این کد را قرار دهید.

# Defining a server group called `client` that has one server in it called `client` on port `3000`.
upstream client {
    server client:3000;
}

# Defining a server group called `server` that has one server in it called `server` on port `5000`.
upstream server {
    server server:5000;
}

# Listening on port 80 and redirecting requests to the client and server.
server {
    listen 80;
    listen [::]:80;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;

    location / {
        proxy_pass http://client;
    }

    location /server {
        rewrite /server/(.*) /$1 break;
        proxy_pass http://server;
    }
}
وارد حالت تمام صفحه شوید

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

  • را upstream دستورالعمل برای تعریف گروه های سرور، یکی برای client در بندر 3000 و دیگری برای server در بندر 5000.
  • را server دستورالعمل برای تعریف سروری که در پورت گوش می دهد استفاده می شود 80 برای درخواست های دریافتی را listen دستورالعمل پورت و proxy_http_version، proxy_set_header، و proxy_cache_bypass دستورالعمل ها برای پیکربندی تنظیمات پراکسی استفاده می شوند.
  • را location دستورالعمل برای تعریف مسیرهای URL که به هر گروه سرور هدایت می شوند استفاده می شود. اولین location / دستورالعمل همه درخواست ها را به client گروه سرور دومین location /server دستورالعمل هر درخواستی را با مسیر مطابقت می دهد /server و استفاده می کند rewrite بخشنامه حذف /server از مسیر قبل از تغییر مسیر به server گروه سرور با استفاده از proxy_pass بخشنامه

حتی من برای اولین بار از NGINX استفاده می کنم، بنابراین لطفاً مقاله ای را که در بالا ذکر کردم بخوانید تا به وضوح نحوه نوشتن فایل های پیکربندی NGINX را درک کنید.

اکنون، Dockerfile را در همان پوشه ایجاد کنید و آن را Paste کنید.

FROM nginx:stable-alpine

RUN rm /etc/nginx/conf.d/*

COPY ./nginx.conf /etc/nginx/conf.d/

CMD [ "nginx", "-g", "daemon off;" ]
وارد حالت تمام صفحه شوید

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

راه اندازی AWS

ما قصد داریم از سه سرویس AWS استفاده کنیم:
1) Elastic Beanstalk – یک سرویس کاملاً مدیریت شده که استقرار برنامه ها را آسان می کند.
2) EC2 – Elastic Compute یک سرویس محاسباتی است که ظرفیت محاسباتی مقیاس پذیر را ارائه می دهد. شما می توانید به سرعت یک ماشین مجازی را با تنظیمات دلخواه خود مانند سیستم عامل، نرم افزار، ذخیره سازی و غیره راه اندازی کنید.
3) سطل S3 – یک سرویس ذخیره سازی بسیار مقیاس پذیر. تمام داده های برنامه شما در اینجا ذخیره می شود.

فقط Elastic Beanstalk باید پیکربندی شود. دو مورد دیگر به طور خودکار پیکربندی می شوند.

بنابراین، پیش بروید و وارد کنسول مدیریت AWS خود شوید.

یک کاربر ایجاد کنید

برای شروع، باید کاربری ایجاد کنیم که منابع ابری را مدیریت کند. از آنجایی که ما در حال خودکار کردن استقرار با GitHub Actions هستیم، به روشی برای Actions نیاز داریم تا منابع ما را تغییر دهد، مانند استقرار کد در AWS، و این همان چیزی است که این کاربر برای آن است. مطمئن شوید که مجوزهای مناسب را اعطا کرده اید.

در نوار جستجو، “IAM” (Identity and Access Management) را تایپ کرده و روی آن کلیک کنید کاربران زیر مدیریت دسترسی.

AWS IM

را کلیک کنید کاربران را اضافه کنید و به کاربر خود یک نام بدهید -> کلیک کنید بعد.

ایجاد کاربر در IAM

که در مجوزها را تنظیم کنید انتخاب کنید خط مشی ها را مستقیماً ضمیمه کنید -> بررسی کنید AdministratorAccess-AWSElasticBeanstalk -> کلیک کنید بعد -> در نهایت کلیک کنید کاربر ایجاد کنید.

تنظیم مجوز برای کاربر

برنامه ای را در Elastic Beanstalk ایجاد و پیکربندی کنید

دوباره در نوار جستجو، “Elastic Beanstalk” را تایپ کنید.

کلیک ایجاد اپلیکیشن.

AWS Elastic Beanstalk

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

ایجاد برنامه در ساقه لوبیا الاستیک

تبریک 🎊! برنامه شما ایجاد شده است. می توانید با کلیک روی URL نشان داده شده در محیط برنامه از آن بازدید کنید. این یک نمونه برنامه ارائه شده توسط EB است.

نمونه برنامه

پیکربندی متغیرهای محیطی

قبل از استقرار برنامه خود، باید متغیرهای محیطی را در EB اضافه کنیم.

برای انجام این کار، به برنامه بروید صفحه پیکربندی و کلیک کنید ویرایش کنید زیر نرم افزار دسته بندی.

اضافه کردن متغیرهای محیطی

به پایین صفحه -> زیر بروید متغیرهای محیطی و متغیرهای env زیر را اضافه کنید.

REACT_APP_BACKEND_URL = /server
MONGODB_URI = your MongoDB URI
TOKEN_KEY = random string
EMAIL = email
PASSWORD = password
وارد حالت تمام صفحه شوید

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

خودشه! اکنون زمان آن است که مرحله استقرار را به خط لوله CI/CD خود اضافه کنیم.

استقرار برنامه MERN در AWS با CI/CD

باز کن pipeline.yml و این مرحله را درست در زیر فشار دادن تصاویر به مرحله داکر هاب اضافه کنید.

      # This is the step that is deploying the application to Elastic Beanstalk.
      - name: Deploy to Elastic Beanstalk
        uses: einaregilsson/beanstalk-deploy@v21
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: ${{ secrets.EB_APP_NAME }}
          environment_name: ${{ secrets.EB_ENV_NAME }}
          region: ${{ secrets.EB_REGION }}
          version_label: "version-${{ github.run_number }}"
          deployment_package: docker-compose.yml
وارد حالت تمام صفحه شوید

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

  • در اینجا ما از یک اکشن GitHub از پیش تعریف شده استفاده می کنیم einaregilsson/beanstalk-deploy@v21 تا نیازی به نوشتن از ابتدا نداشته باشیم. نیازی به توضیح نیست، خیلی ساده است.
  • اضافه کردن AWS_ACCESS_KEY_ID، AWS_SECRET_ACCESS_KEY به اسرار GitHub. می توانید اینها را از داشبورد IAM دریافت کنید. فقط روی کاربری که ایجاد کردید کلیک کنید و به آن بروید مدارک امنیتی را برگه و از آنجا کپی کنید.
  • EB_APP_NAME نام برنامه EB شما است و EB_ENV_NAME نام محیط برنامه شما است (به “-env” ختم می شود، در مورد من “Productivityapp-env” است).
  • EB_REGION منطقه ای است که به شما اختصاص داده شده است.

منطقه ساقه لوبیا الاستیک

از آنجایی که docker-compose نمی‌تواند متغیرهای محیط GitHub را بخواند، اکنون در حال ایجاد یک تصویر دوم با کلمه “آخرین” در انتهای تگ تصویر به جای github.run_number. این فایل نهایی YAML است. (در صورت تمایل می توانید یک تصویر واحد بسازید، فقط برچسب را با آن حذف کنید github.run_number)

# The name of the workflow.
name: Build and Deploy

# Run the workflow when code is pushed to the main branch
on:
  push:
    branches:
      - main

# Set environment variables
env:
  MONGODB_URI: ${{ secrets.MONGODB_URI }}
  TOKEN_KEY: ${{ secrets.TOKEN_KEY }}
  EMAIL: ${{ secrets.EMAIL }}
  PASSWORD: ${{ secrets.PASSWORD }}

# This is the workflow that is being run.
jobs:
  build-and-deploy:
    # This is telling GitHub to run the workflow on the latest version of Ubuntu.
    runs-on: ubuntu-latest
    steps:
      # Checkout the code from the GitHub repository
      - name: Checkout code
        uses: actions/checkout@v3

      # Install dependencies and run tests for the client application
      - name: Install and Test Client
        working-directory: ./client
        run: |
          npm install
          npm run test

      # Install dependencies, export environment variables to be used by application and run tests for the server application
      - name: Install and Test Server
        working-directory: ./server
        run: |
          npm install
          export MONGODB_URI=$MONGODB_URI
          export TOKEN_KEY=$TOKEN_KEY
          export EMAIL=$EMAIL
          export PASSWORD=$PASSWORD
          npm run test

      # Build a Docker image for the client application
      - name: Build Client Docker Image
        working-directory: ./client
        # Build image with tag rakeshpotnuru/productivity-app:client
        run: |
          docker build -t rakeshpotnuru/productivity-app:client-${{github.run_number}} -t rakeshpotnuru/productivity-app:client-latest .

      # Build a Docker image for the server application
      - name: Build Server Docker Image
        working-directory:
          ./server
          # Build image with tag rakeshpotnuru/productivity-app:server
        run: |
          docker build -t rakeshpotnuru/productivity-app:server-${{github.run_number}} -t rakeshpotnuru/productivity-app:server-latest .

      # Build a Docker image for the NGINX reverse proxy
      - name: Build NGINX Docker Image
        working-directory: ./nginx
        # Build image with tag rakeshpotnuru/productivity-app:nginx
        run: |
          docker build -t rakeshpotnuru/productivity-app:nginx-${{github.run_number}} -t rakeshpotnuru/productivity-app:nginx-latest .

      # Login to Docker Hub using credentials from repository secrets
      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      # Push the Docker images to Docker Hub
      - name: Push Docker Images to Docker Hub
        run: |
          docker push rakeshpotnuru/productivity-app:client-${{github.run_number}}
          docker push rakeshpotnuru/productivity-app:server-${{github.run_number}}
          docker push rakeshpotnuru/productivity-app:nginx-${{github.run_number}}
          docker push rakeshpotnuru/productivity-app:client-latest
          docker push rakeshpotnuru/productivity-app:server-latest
          docker push rakeshpotnuru/productivity-app:nginx-latest

      # This is the step that is deploying the application to Elastic Beanstalk.
      - name: Deploy to Elastic Beanstalk
        uses: einaregilsson/beanstalk-deploy@v21
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: ${{ secrets.EB_APP_NAME }}
          environment_name: ${{ secrets.EB_ENV_NAME }}
          region: ${{ secrets.EB_REGION }}
          version_label: "version-${{ github.run_number }}"
          deployment_package: docker-compose.yml
وارد حالت تمام صفحه شوید

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

deployment_package

دو راه وجود دارد که می توانید یک بسته برای استقرار بسته ارائه دهید – 1. فایل فشرده یا 2. فایل docker-compose. از آنجایی که ما تصاویر را به هاب docker هل می دهیم، از آن استفاده خواهیم کرد docker-compose.yml فایل.

نام قبلی را تغییر دهید docker-compose.yml فایل به عنوان docker-compose.dev.yml و جدید ایجاد کنید docker-compose.yml فایل. این کد را جایگذاری کنید.

version: "3.8"

services:
  nginx:
    image: rakeshpotnuru/productivity-app:nginx-latest
    restart: always
    depends_on:
      - client
      - server
    ports:
      - "80:80"

  client:
    image: rakeshpotnuru/productivity-app:client-latest
    environment:
      - CHOKIDAR_USEPOLLING=true
      - REACT_APP_BACKEND_URL=${REACT_APP_BACKEND_URL}

  server:
    image: rakeshpotnuru/productivity-app:server-latest
    environment:
      - MONGODB_URI=${MONGODB_URI}
      - TOKEN_KEY=${TOKEN_KEY}
      - EMAIL=${EMAIL}
      - PASSWORD=${PASSWORD}
وارد حالت تمام صفحه شوید

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

  • به جای ساخت مجدد تصاویر Docker با Dockerfile، تصاویر از پیش ساخته شده را از Docker Hub می کشیم. و آن متغیرهای محیطی از متغیرهایی که قبلاً در محیط برنامه EB تعریف کردیم مشتق شده‌اند.

همین! کد را به GitHub فشار دهید و اجازه دهید تمام بررسی ها در گردش کار GitHub Actions عبور کنند. شما می توانید برنامه خود را در عمل ببینید 🎉🚀🤩.

صفحه ورود به برنامه مستقر شده

صفحه اصلی برنامه مستقر شده

پایان دادن به محیط زیست

میم نمونه aws را خاموش کنید

فراموش نکنید که پس از اتمام این آموزش، اگر دیگر از آن برنامه استفاده نمی کنید، محیط را خاتمه دهید.

برای خاتمه، به محیط ها -> محیطی را که می خواهید خاتمه دهید انتخاب کنید -> کلیک کنید اقدامات -> کلیک کنید محیط را خاتمه دهید. این کار همچنین هر نمونه ای را که توسط برنامه شما ایجاد شده بود، خاتمه می دهد.

خاتمه محیط ساقه لوبیا الاستیک


اگر تا این حد از «بیایید یک برنامه وب MERN را با پشته کامل بسازیم و مستقر کنیم» فاصله گرفته‌اید، آفرین. به خود شانه بزنید.


این پایان ماجرا نیست. بسیاری از مقالات هیجان انگیز در راه است! برای اطلاعات بیشتر من را دنبال کنید – به بعد و بالاتر 🚀!

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

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

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

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