Anophel-آنوفل Docker برای مبتدیان: ایجاد محیط توسعه Backend

Docker برای مبتدیان: ایجاد محیط توسعه Backend

انتشار:
1

در این مقاله می خواهم درباره داکر Docker برای مبتدیان صحبت کنم.و در ابتدا با داکر آشنا خواهیم شد و سپس از داکر در پروژه بک اند استفاده خواهیم کرد.ممکن است در اوایل برنامه نویسی با Docker آشنایی چندانی نداشته باشید و فقط در حد شنیدن اسم آن باشد. اما بعد ها متوجه خواهید شد که داکر به دلایل زیر مهم است که درباره آن آشنایی داشته باشید:

  • کاهش بار روی RDS در محیط توسعه (عدم استفاده از RDS).
  • حذف اثرات مهاجرت بین اعضای تیم (حل مشکل DB مشترک).
  • تسریع در راه اندازی محیط توسعه (تسریع در روند ساخت).
  • بهبود دردسر راه اندازی مجدد سرور به دلیل تایم اوت های بیکار.
     

ما DB موجود خود را به یک DB کانتینری منتقل کنم و از docker-compose برای راه اندازی backend و DB استفاده خواهیم کرد.در ابتدا با داکر سپس نحوع استفاده از آن را یاد خواهیم گرفت.

داکر Docker چیست؟

داکر، زیرمجموعه ای از پروژه موبی، یک چارچوب نرم افزاری برای ساخت، اجرا و مدیریت کانتینرها بر روی سرورها و ابر است. اصطلاح "docker" ممکن است به ابزارها (فرمان‌ها و دیمون) یا فرمت فایل Dockerfile اشاره داشته باشد.

قبلاً زمانی که می‌خواستید یک برنامه وب را اجرا کنید، یک سرور خریداری می‌کردید، لینوکس را نصب می‌کردید، یک stack LAMP راه‌اندازی می‌کردید و برنامه را اجرا می‌کردید. اگر برنامه شما محبوب شد، با راه‌اندازی سرور دوم، تعادل بار را به خوبی انجام دادید تا مطمئن شوید که برنامه در اثر ترافیک زیاد خراب نمی‌شود.

با این حال، زمان تغییر کرده است، و به جای تمرکز بر روی سرورهای منفرد، اینترنت بر روی آرایه‌هایی از سرورهای وابسته و اضافی در سیستمی ساخته شده است که معمولاً the cloud نامیده می‌شود. به لطف نوآوری هایی مانند فضاهای نام هسته لینوکس و cgroup ها، مفهوم سرور را می توان از محدودیت های سخت افزاری حذف کرد و در عوض، اساساً به یک نرم افزار تبدیل شد. این سرورهای مبتنی بر نرم‌افزار کانتینر نامیده می‌شوند و ترکیبی از سیستم‌عامل لینوکس هستند که روی آن اجرا می‌شوند، به‌علاوه یک محیط زمان اجرا بیش از حد محلی.

کانتینرها Containers چیست؟

کانتینرها اغلب با ماشین های مجازی مقایسه می شوند، اما تفاوت های مهمی بین این دو وجود دارد. ماشین‌های مجازی یک نسخه کامل از یک سیستم عامل را اجرا می‌کنند، در حالی که کانتینرها هسته میزبان را با سایر کانتینرها به اشتراک می‌گذارند. این باعث می شود کانتینرها بسیار سبک تر و کارآمدتر از ماشین های مجازی باشند.

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

این کانتینرها از یکدیگر جدا شده‌اند و ابزارها، کتابخانه‌ها و فایل‌های پیکربندی خود را در کنار هم قرار می‌دهند و می‌توانند از طریق کانال‌های کاملاً مشخص با یکدیگر ارتباط برقرار کنند.

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

Builder: ابزار یا مجموعه ای از ابزارهای مورد استفاده برای ساخت یک کانتینر، مانند distrobuilder برای LXC، یا Dockerfile برای Docker.

Engine: برنامه ای است که برای اجرای یک کانتینر استفاده می شود. برای Docker، این به دستور docker و daemon dockerd اشاره دارد. برای دیگران، این می تواند به دیمون کانتینر و دستورات مربوطه (مانند podman) اشاره کند.

Orchestration: فناوری مورد استفاده برای مدیریت بسیاری از کانتینرها، از جمله Kubernetes و OKD.

کانتینرها اغلب هم یک برنامه کاربردی و هم پیکربندی را ارائه می دهند، به این معنی که یک sysadmin در مقایسه با زمانی که یک برنامه از یک منبع سنتی نصب می شود، نیازی به صرف زمان زیادی برای اجرای یک برنامه در یک کانتینر ندارد. Dockerhub و Quay.io مخازنی هستند که تصاویر را برای استفاده توسط موتورهای کانتینر ارائه می دهند.

1. ایجاد فایل های مرتبط با Docker

ما یک سرویس داریم که شامل چند فرانت اند (/frontend/.) و بک اند (/backend/.) می شود، در یک monorepo (فرانت اند React است، بک اند NestJS است).

در حالی که docker-compose به ما امکان می‌دهد این سرویس‌ها را به طور جمعی راه‌اندازی کنیم، برخی از فرانت‌اندها در حال توسعه فعال نیستند، بنابراین در حال حاضر، ما تصمیم گرفته‌ایم تنها بک اند و DB لازم را در کانتینرهای Docker راه‌اندازی کنیم.

ایجاد Dockerfile

ابتدا اجازه دهید Dockerfile (Dockerfile.dev) را برای Backend ایجاد کنیم، به صورت زیر:

FROM node:18.15.0

# Set timezone to Tokyo (IRST)
ENV TZ=Asia/Tehran
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR /app

# Copy package dependencies
COPY package*.json ./

# Ignore prepare script to avoid husky install errors
RUN yarn install --ignore-scripts

EXPOSE 8000

CMD ["yarn", "start:dev"]

منطقه زمانی روی IRST تنظیم شده است زیرا DB موجود (RDS) در IRST پیکربندی شده است. همچنین، در مرحله نصب هاسکی به مشکل خوردیم، بنابراین آن را طوری تنظیم کرده‌ایم که هنگام نصب وابستگی‌ها با Yarn با استفاده از گزینه ignore-scripts-- ، اسکریپت‌ها را نادیده بگیرد.

ایجاد docker-compose.yml

سپس فایل docker-compose.yml را به صورت زیر ایجاد می کنیم. این فایل کانتینرهای backend و DB (MySQL) را مدیریت می کند.

version: "3.9"

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.dev
    ports:
      - "3010:3010" # Map local and container ports
    depends_on:
      - db # Wait for DB service to start
    env_file: ./backend/.env # Specify environment variables
    volumes:
      - ./backend:/app # Map host and container directories

  db:
    image: mysql:8.0.28
    platform: linux/x86_64
    container_name: db
    env_file: ./backend/.env # Specify environment variables
    volumes:
      - db-data:/var/lib/mysql # Persist data
    ports:
      - "3306:3306" # Map local and container ports
    command: --default-authentication-plugin=mysql_native_password --sql_mode=NO_ENGINE_SUBSTITUTION

volumes:
  db-data: # Define volume to persist DB data

با استفاده از Dockerfile.dev و docker-compose.yml که به تازگی ایجاد کرده ایم، اکنون می توانیم بک اند و DB را راه اندازی کنیم.

اگر به یک frontend نیاز دارید، می توانید یک Dockerfile را در /frontend/. مثل مراحل مشابه بالا ایجاد کنید، و یک سرویس را به docker-compose.yml اضافه کنید تا این مورد را انجام دهد.


دقت کنید در MySQL، بسته به پیکربندی DB، یک فیلد از نوع DATETIME بدون مقدار پیش‌فرض می‌تواند به طور خودکار روی 0000-00-00 00:00:00 تنظیم شود. با این حال، این پیکربندی در کانتینر DB وجود نداشت و در نتیجه پس از راه‌اندازی کانتینر خطاهای INSERT ایجاد شد.

سپس پیکربندی MySQL را به صورت زیر تأیید می کنیم:

SHOW VARIABLES;

هنگام بررسی sql_mode، تنظیمات مختلفی بین DB کانتینر و DB موجود (RDS) پیدا می شود. بنابراین، sql_mode=NO_ENGINE_SUBSTITUTION-- را به دستور db اضافه کنید.

# Container DB
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

# Existing DB (RDS)
NO_ENGINE_SUBSTITUTION


دقت کنید که ما در حال مدیریت یک سرویس مونورپو هستیم و فرانت‌اند را کانتینری نمی‌کنیم. با این حال، از آنجایی که این احتمال وجود دارد که frontend در آینده کانتینری شود، ما docker-compose.yml را در فهرست اصلی قرار می دهیم. برای بارگیری backend/Dockerfile.dev/.، عبارت زیر را انجام داده:

build:
  context: ./backend
  dockerfile: Dockerfile.dev

ما آن را تنظیم کرده ایم تا تنظیمات اتصال MySQL را از env_file بخواند: backend/.env/..

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

اطلاعات پیکربندی DB را به backend/.env/. به عنوان Environment Variables (هر مقدار) اضافه کنید.

MYSQL_ROOT_PASSWORD=
MYSQL_DATABASE=
MYSQL_USER=
MYSQL_PASSWORD=

برای مثال:

MYSQL_DATABASE=db_local
MYSQL_USER=admin

3. راه اندازی کانتینر

دستور زیر را در دایرکتوری ریشه اجرا کنید تا چندین کانتینر (بک‌اند، DB) راه‌اندازی شود.

$ docker-compose up

4. MySQL Workbench Setup

با استفاده از MySQL Workbench به MySQL DB در Docker متصل شوید.

1.MySQL Workbench را باز کنید.
2.روی دکمه [+] در لیست اتصالات MySQL در سمت چپ صفحه کلیک کنید.
تنظیمات اتصال را به صورت زیر تنظیم کنید:


نام اتصال: هر نام اتصال (مثال: db-local-docker)
نام Hostname (میزبان): localhost (یا آدرس IP میزبانی که Docker در آن اجرا می شود)
پورت: 3306 (شماره پورت در docker-compose.yml تنظیم شده است)
نام کاربری: MYSQL_USER از backend/.env/.
رمز عبور: MYSQL_PASSWORD از backend/.env/.


3.برای انجام آزمایش اتصال، روی [Test Connection] کلیک کنید. اگر مشکلی وجود ندارد، برای ذخیره اتصال روی [OK] کلیک کنید.

5. استخراج کردن Dump از دیتابیس موجود

Dump (اطلاعات و داده های جدول) را از RDS برای MySQL DB که در محیط توسعه دهنده استفاده می شود، استخراج کنید.

شما از پورت ماشین محلی (<local_port>) از طریق یک سرور پرش (<ssh_user>@<remote_server_ip>) به پورت RDS (<remote_database_port>) (تونل SSH) متصل خواهید شد.

برای جلوگیری از تداخل پورت، مانند زمانی که MySQL از قبل روی ماشین محلی در حال اجرا است، این بار از پورت های مختلف برای local_port و remote_database_port استفاده خواهیم کرد.

$ ssh -f -N -L <local_port>:<remote_database_url>:<remote_database_port> -i <path_to_your_ssh_key> <ssh_user>@<remote_server_ip>

local_port: پورتی که می‌خواهید در دستگاه محلی خود باز کنید (به عنوان مثال، 3307)
remote_database_url: این URL دیتابیس راه دور است(به عنوان مثال database.db.coedadadas22.ap-northeast-1.rds.amazonaws.com)
remote_database_port: پورتی که توسط دیتابیس راه دور استفاده می شود (به عنوان مثال، 3306)
path_to_your_ssh_key: مسیر به کلید SSH شما (به عنوان مثال، ~/.ssh/db-pem-key.pem)
ssh_user: نام کاربری مورد استفاده برای اتصال به سرور راه دور (به عنوان مثال، ec2-user)
remote_server_ip: آدرس IP سرور راه دور (به عنوان مثال، 54.168.32.10)
شما به پورت (<local_port>) لوکال هاست متصل خواهید شد و تمام نام جدول DB مربوطه (<database_name>) را روی RDS در یک فایل متنی (<output_file>) می نویسید.

$ mysql -h <localhost_ip> -P <local_port> -u <username> -p <database_name> -e 'show tables' | tail -n +2 > <output_file>

localhost_ip: آدرس IP میزبانی که کلاینت MySQL در آن اجرا می شود (به عنوان مثال، 127.0.0.1)
local_port: پورت دستگاه محلی شما برای دسترسی به دیتابیس راه دور از طریق ارسال پورت SSH (به عنوان مثال، 3307)
username: نام کاربری مورد استفاده برای اتصال به دیتابیس (به عنوان مثال، مدیر)
database_name: نام دیتابیس ای که به آن متصل می شوید (به عنوان مثال db-prod)
output_file: نام فایل برای ذخیره نام جدول به دست آمده از دیتابیس (به عنوان مثال، all_tables.txt)
دیتابیس را بر اساس لیست جداولی که می خواهید صادر کنید، تخلیه کنید.

$ mysqldump -h <localhost_ip> -P <local_port> -u <username> -p <database_name> $(cat <tables_list_file>) > <output_file>

localhost_ip: آدرس IP میزبان دیتابیس (به عنوان مثال، 127.0.0.1)
local_port: پورتی که دیتابیس به آن گوش می دهد (به عنوان مثال، 3307)
username: نام کاربری برای اتصال به دیتابیس (به عنوان مثال، مدیر)
database_name: نام دیتابیس برای ایجاد یک Dump از (به عنوان مثال، db-prod)
tables_list_file: فایل حاوی لیست جداول برای ایجاد یک Dump از (به عنوان مثال، all_tables.txt)
output_file: نام فایل برای ذخیره خروجی (فایل dump) (به عنوان مثال database_export.sql)
 

6. وارد کردن Dump به دیتابیس کانتینر

ما Dump را از MySQL Workbench به دیتابیس کانتینر وارد می کنیم.

1.MySQL Workbench را باز کنید.
2.از صفحه اصلی روی اتصال دیتابیس ای که می خواهید به آن متصل شوید کلیک کنید.
3.هنگامی که اتصال دیتابیس باز شد، "Server" -> "Data Import" را از نوار منو انتخاب کنید.
4.هنگامی که صفحه "Data Import" ظاهر شد، "Import from Self-Contained File" را انتخاب کنید، سپس روی دکمه "..." در سمت راست کلیک کنید تا فایل SQL مورد نظر برای وارد کردن را انتخاب کنید.
5.دیتابیس مقصد را برای وارد کردن از منوی کشویی "Default Target Schema" انتخاب کنید.
6.روی دکمه "Start Import" در بخش "Import Progress" کلیک کنید.

و تمام.

خلاصه

ما در این مقاله با بررسی داکر و نحوه استفاده از آن در پروژه بک اند را یاد گرفتیم و دلیل استفاده از این کار کاهش بار روی RDS در محیط توسعه ، حل مشکل DB مشترک ،تسریع در راه اندازی محیط توسعه و بهبود دردسر راه اندازی مجدد سرور به دلیل تایم اوت های بیکار می باشد.

#توسعه_وب#داکر#داکر_کانتینر#docker#طراحی_وب
نظرات ارزشمند شما :

در حال دریافت...

مقاله های مشابه

در حال دریافت...