یک سناریو کاربردی با NGINX

در این پست قصد دارم که یک سناریو کاربردی و آموزشی را که با NGINX و در محیط داکر پیاده سازی شده است را توضیح دهم. مخاطب این مطلب کسانی هستند که با عملکرد DNS و ریکورد های DNS Server، وب سرور، داکر و نحوه خواندن کانفیگ فایل های در گنو/لینوکس آشنا هستند. در ابتدا توضیحاتی درباره سناریو داده خواهد شد و در ادامه به تنظیمات NGINX و پیاده سازی سناریو در داخل داکر با استفاده از داکر کامپوز پرداخته میشود.

در این پست قرار است که درخواست های یک دامنه و تمامی زیر دامنه های آن در یک وب سرور NGINX به صورت متمرکز کنترل شود. وب سرور NGINX قرار است که در پس زمینه هر درخواست برای دامنه mobit.com را برای سایت mobit.ir و درخواست ها هر زیر دامنه آن را به یک سرور دیگر که فقط خود NGINX به آن دسترسی دارد ارسال کند و پاسخ را به کاربر بدهد. برای پیاده سازی این سناریو از proxy_pass در NGINX استفاده خواهیم کرد.




برای کانفیگ NGINX قرار هست که به ازای دامنه mobit.com و هر زیر دامنه آن یک فایل کانفیگ برای NGINX وجود داشته باشد که دستور العمل برخورد با هر کدام از درخواست ها به وب سرور داده شود.

کانفیگ فایل برای برخورد با درخواست های mobit.com با نام mobit.com.conf به شکل زیر میباشد که درباره تمام آن در ادامه توضیح داده خواهد شد:

 server {
             listen 80 default_server;
             listen [::]:80 default_server;
             server_name mobit.com;
             location / {
             proxy_pass         https://mobit.ir; 
             proxy_redirect     off;
             proxy_set_header   Host $host;
             proxy_set_header   X-Real-IP $remote_addr;
             proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header   X-Forwarded-Host $server_name;
             }
}
  1. در خط اول با server مشخص میکنیم که تنظیمات سرور ما به شکل زیر خواهد بود.
  2. در خط دوم و سوم مشخص میکنیم که سرور ما روی چه پورتی سرویس دهد و با default_server میگوییم که اگر هر درخواست دیگری که با تمام شرایط وب سرور تطابق نداشت، به صورت پیشفرض از تنظیمات این سرور برای درخواست به کاربر استفاده شود.
  3. در خط چهار گفته میشود که برای پاسخ به دامنه mobit.com از این کانفیگ استفاده شود. با توجه به اینکه در خط قبل از default_server استفاده کردیم برای تمام درخواست های تعریف نشده هم از این کانفیگ استفاده خواهد شد.
  4. در خط پنجم گفته میشود که تمام درخواست ها از مسیر اصلی به بعد از کانفیگ های ذکر شده استفاده شود.
  5. در خط ششم گفته میشود که تمام درخواست های کاربر به وب سرور در پس زمینه به mobit.ir ارسال شود.
  6. در خط هفتم گفته میشود از تغییرات در url توسط سرور پاسخ دهنده جلوگیری شود.
  7. از خط هشتم تا یازدهم گفته میشود که در هدر پکت (packet) درخواست تغییراتی داده شود.
  8. در خط دوازدهم و سیزدهم گفته شده است که تنظیمات سرور و مسیر تمام شده است.


قرار هست برای کنترل درخواست زیر دامنه دیگر به آدرس helloworld.mobit.com و apache.mobit.com ، دو کانفیگ فایل مشابه وجود داشته باشد که تنها تفاوت آنها در نام کانفیگ فایل، عدم وجود default_server در خط دوم و سوم و تغییر مقدار مقابل proxy_pass در خط پنجم میباشد.



تا اینجای کار با نحوه کانفیگ وب سرور NGINX آشنا شدیم در ادامه به اجرای NGINX در داخل کانتینر با تنظیمات مورد نظرمان میپردازیم.

برای راه اندازی NGINX با کانفیگ دلخواه خودمان از داکر فایل زیر (در صورتی که با داکر فایل آشنا نیستید در اینجا توضیحات کاملی داده شده است) استفاده میکنیم.

FROM nginx:latest
MAINTAINER AmirHosein Nematzadeh <me@amirhne.me>
RUN rm -f /etc/nginx/conf.d/default.conf
COPY ./nginx_config /etc/nginx/conf.d/
  1. در خط اول گفته میشود که ایمیج مورد نظر ما از چه ایمیجی ساخته شود.
  2. در خط دوم نام و اطلاعات فردی که سازنده ایمیج هست ذکر شده است.
  3. در خط سوم کانفیگ فایل پیشقرض NGINX حذف میشود
  4. در خط چهارم کلیه کانفیگ فایل های روی سیستم در مسیری کانفیگ فایل های NGINX قرار میگیرد.

با استفاده از این داکر فایل میتوانیم NGINX مورد نظرمان را برای پیاده سازی سناریو داشته باشیم. در ادامه برای پیاده سازی سناریو از داکر کامپوز استفاده میکنیم.



داکر کامپوز به منظور راه اندازی چند کانتیر وابسته به صورت هزمان در یک پروژه مورد استفاده قرار میگردد که بسیار بهینه تر و سریع تر از دستور docker run برای راه اندازی هر کانتینر به صورت دستی میباشد. داکر کامپوز از یک فایل YAML برای راه اندازی و کانفیگ کانتیتر ها استفاده میکند.

نام پیشفرض فایل YAML که برای داکر کامپوز استفاده میشود، docker-compose.yml میباشد که برای سهولت اجرای دستور داکر کامپوز از این نام استفاده میشود.

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

   version: '3.8'
   services:
    nginx_for_subdomain_scenario:
       build:
         context: .
         dockerfile: nginx.Dockerfile
       ports: 
         - '80:80'
       depends_on:
        - helloworld
        - apache
    helloworld:
       image: amirhne/hello_world_flask_app
    apache:
       image: httpd
  1. در خط اول نسخه فایل YAML مشخص میشود که آخرین نسخه انتخاب شده است.
  2. در خط دوم گفته شده است که کانینر های راه اندازی شده چه خواهند بود.
  3. در خط سوم نام کانتینر NGINX مشخص میشود که مشابه docker run --name هست.
  4. در خط چهارم مشخص میشود که کانتینر بایستی از رو یک داکر فایل ساخته شود.
  5. در خط پنجم مسیر داکر فایل مشخص میشود که مسیری است که فایل YAML در آن قرار دارد. این همان داکر فایلی هست که نحوه ساخت آن قبل تر توضیح داده شد.
  6. در خط ششم نام داکر فایل داده میشود.
  7. در خط هفتم گفته میشود که چه پورت هایی از خارج کانتینر در دسترس باشند مشابه دستور: docker run -p
  8. در خط هشتم مشخص میشود چه پورتی از کانتینر به چه پورتی از بیرون فوروارد شود.
  9. در خط نهم مشخص میشود که این کانتینر وابسته به راه اندازی چه کانتینر هایی میباشد.
  10. در خط دهم و یازدم نام کانتینرهایی که NGINX به آن وابسته هست داده شده است.
  11. در خط دوازدهم نام کانتیتر جدید برای راه اندازی داده شده است.
  12. در خط سیزدهم گفته شده است که این کانتینر از چه ایمیجی از روی داکر هاب ساخته شود. این همان ایمیجی هست که در مطلب قبلی ساخته شده است و یک اپلیکشن ساده تحت وب میباشد.
  13. در خط چهاردهم نام کانتیتر جدید برای راه اندازی داده شده است.
  14. در خط پانزدهم گفته شده است که این کانتینر از چه ایمیجی از روی داکر هاب ساخته شود. این ایمیج وب سرویس آپاچی هست که یه صفحه وب ساده به صورت پیشفرض روی آن در دسترس میباشد.

نکته مهم: فاصله ها در این فایل بسیار مهم میباشد و بایستی حتما سلسله مراتب در نوشتن این فایل رعایت شود.

نکته مهم: داکر دارای یک DNS سرور داخلی در هر شبکه خود هست و تمام کانتیر هایی که در یک شبکه قرار دارند تنها با نام میتوانند با یکدیگر ارتباط برقرار کنند. با استفاده از همین قابلیت در کانفیگ فایل های NGINX که برای دو زیر دامنه ایجاد شده اند در خط ششم و قسمت proxy_pass فقط نام کانتینر قرار داده شده است. یعنی به شکل زیر:

proxy_pass          http://helloworld:5000;

و

proxy_pass           http://apache;

با استفاده از این قابلیت درخواست ها به سمت این دو کانتینر هدایت میشوند.



این فایل کانفیگ تمامی تنظیمات لازم برای راه اندازی سناریو ما را دارد که تنها بایستی اجرا شود ولی قبل از آن بایستی مشخص کرد که برای دامنه های مورد نظر برای باز شدن به چه آی پی ترجمه (Resolve) شوند. از انجایی که سناریو مورد نظر فقط قرار هست که بر روی ماشین محلی اجرا شود میتوان با ویرایش فایل hosts سیستم عامل ماشینتان بگویید که این وب سایت روی ماشین محلی هستند.

برای این کار ریکورد های زیر را به فایل hosts سیستم تان اضافه کنید:

127.0.0.1                   mobit.com
127.0.0.1                   www.mobit.com
127.0.0.1                   helloworld.mobit.com
127.0.0.1                   apache.mobit.com

فایل hosts در سیستم عامل گنو/لینوکس در مسیر زیر قرار دارد:

/etc/hosts

و در سیستم عامل ویندوز در مسیر زیر قرار دارد:

c:\Windows\System32\Drivers\etc\hosts

در ادامه میتوانید تمام پروژه را که شامل تمامی کانفیگ فایل ها، داکر فایل و فایل داکر کامپوز هست را با دستور زیر از گیتهاب دریافت کنید و به مسیر پروژه بروید:

git clone https://github.com/amirhne/nginx-subdomain-scenario.git
cd nginx-subdomain-scenario

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

docker-compose up -d

حالا میتوانید با رفتن به دامنه http://mobit.com سایت mobit.ir و http://helloworld.mobit.com وب اپلیکیشن فلسک و http://apache.mobit.com وب سرور اپاچی را باز کنید.

برای بستن پروژه هم باید از دستور زیر استفاده کنید:

docker-compose down --rmi local

امیدوارم این مطلب برای شما مفید بوده باشد.