طرح‌چه

وب سرور برای فایل های استاتیک | Nginx from stratch

۷ تیر ۱۴۰۴

وب سرور برای فایل های استاتیک | Nginx from stratch
یک وب سرور برای فایل های static ایجاد میکنیم , با فایل های مهم nginx آشنا میشیم و یکسری از دستورات اولیه رو مرور میکنیم.

فرض کنید یکسری فایل داریم و میخواهیم آنها را از طریق سرور با استفاده از یک آدرس وب با کاربرهای خودمون به اشتراک بزاریم. ما میتونیم از nginx استفاده کنیم و اون رو طوری تنظیم کنیم که فایل ها رو روی ادرس مورد نظر ما برای کاربرها لود کنه.

در قسمت قبل با بررسی فایل ‍/etc/nginx/nginx.conf متوجه شدیم هر فایلی که با پسوند conf در مسیر /etc/nginx/conf.d/ ایجاد کنیم به عنوان تنظیمات در بلاک HTTP لود میشود. بنابراین ما میتونیم فایل های استاتیک خودمون رو در پوشه ای به نام public در یک مسیر دلخواه قرار بدیم و تنظیمات وب سرور خودمون رو با ایجاد یک فایل با پسوند conf در مسیر /etc/nginx/conf.d‍‍ ذخیره کنیم. 

من اسم فایل تنظیمات خودم رو ‍static01.conf میزارم و درون این فایل دستورات زیر رو قرار میدم و سپس با استفاده از سیگنال reload که در قسمت قبل باهاش آشنا شدیم به nginx میگم که تنظیمات رو دوباره بخونه و خودشو مطابق با اون تنظیم کنه.

server {
    listen 8000 default_server;

    location / {
        root /var/www/public;

        index index.html;
    }
}

در دستورات بالا اولین خط server است یعنی ما میخواهیم یک سرور ایجاد کنیم. سپس با استفاده از { و } بدنه دستورات server را مشخص میکنیم.

دستور listen مشخص میکند که سرور ما به کدام پورت برای دریافت درخواست ها باید گوش دهد. در اینجا پورت 8000 رو مشخص کنیم و با استفاده از default_server مشخص میکنیم که تمامی درخواست هایی که روی این پورت بیاد به صورت دیفالت توسط این سرور مدیریت میشه.

با استفاده از دستور location میتونیم یک نوع روتینگ انجام بدیم. تمامی ادرس های وب دارای بخشی به نام path هستن. به قسمتی که بعد از host قرار میگیره path میگیم.

https://www.example.com/lets/go/to/the/moon

برای مثال , در آدرس بالا ‍lets/go/to/the/moon همون path یا مسیر درخواست است. 

ما در تنظیمات خودمون از / استفاده کردیم. هر وقت در انتهای آدرسی که برای  location مشخص کرده ایم ‍/ داشته باشیم, آن ادرس و تمامی زیر ادرس های آن تطبیق داده میشوند. root یعنی اینکه درخواست ها رو به این مسیر روی هارد دیسک بفرست و index فایل پیش فرضی که باید لود شود را مشخص میکند.

دستور root در Nginx برای مشخص کردن مسیر فایل‌های استاتیک روی سیستم استفاده می‌شود, وقتی از root استفاده می‌کنی، مسیر درخواست به مسیر فایل اضافه می‌شود. یعنی مسیر (path) درخواستی که location با آن تطبیق میکند به انتهای مسیری که در root مشخص کردیم اضافه میشود و سپس نتیجه نهایی آدرسی است که فایل ها با توجه به آن از روی دیسک باید خوانده شوند. برای مثال اگر کاربر آدرس زیر را درخواست بدهد:

http://example.com/images/pic.jpg

nginx دنبال فایل زیر روی دیسک میگردد:

/var/www/public/images/pic.jpg

پس یعنی مسیر تطبیق داده شده با location به مسیر root اضافه می‌شود.

من یکسری عکس توی پوشه public قرار دادم و یک فایل index.html ایجاد کردم و توی تنظیمات به عنوان فایل پیش فرض برای لود شدن معرفی کردم. پس اگه کاربر توی آدرسی که وارد میکنه مستقیم به فایلی اشاره نکنه index.html براش باز میشه. (فایل هایی که من توی این مثال استفاده کردم را از Github دانلود کنید.)

اگر با استفاده از مرورگر خود به آدرس localhost:8000 یا 127.0.0.1:8000 برید باید فایل index.html برای شما نمایش داده شود. اگر از فایل هایی که من در گیت هاب قرار دادم استفاده کرده باشید, باید چیزی شبیه زیر در مرورگر خودتون ببینید:

article figures

در صورتی که docker و make رو نصب کردین: میتونید فایل های مربوط به مثال بالا رو از گیت هاب دانلود کنید. سپس به درون پوشه 01-serving-static-content برید و دستور make up رو درون خط فرمان اجرا کنید. این دستور یک nginx توسط داکر اجرا میکند و تنظیماتی که در قسمت قبل به آن اشاره کردیم رو نیز انجام میدهد. سپس در پورت 8000 روی localhost‍ یا 127.0.0.1 باید تصویر بالا رو بتونید ببینید. وقتی دیگه nginx رو لازم ندارید میتونید درون پوشه ای که گفته شد دستور make down رو بزنید تا داکر اون رو قطع و حذف کند.

دستور alias و تفاوت آن با root

ممکن است در مواقعی بخوایم فایل ها دقیقا آدرسی که روی دیسک مشخص کردیم خوانده شوند و مسیر درخواستِ تطبیق داده شده به مسیری که ما برای فایل ها مشخص کردیم اضافه شود اما قسمتی که در location مشخص کردیم از آن حذف شود. در چنین مواقعی میتوان بجای root از alias استفاده کرد. برای مثال اگر کاربر ادرس زیر را باز کند:

http://www.example.com/home/images/pic.jpg

ما میخواهیم فایل ها را از آدرس زیر لود کنیم:

/var/www/public/images/pic.jpg

 برای اینکار, یه فایل جدید با پسوند conf بسازید و تنظیمات زیر رو درون اون قرار بدید:

server {
    listen 8001 default_server;

    location /home {
        alias /var/www/public;

        index index.html;
    }
}

پورت رو از 8000 به 8001 تغییر دادیم و بجای root از alias استفاده کردیم, همچنین توی این مثال فقط به درخواست هایی که روی آدرس /home ارسال میشن پاسخ میدیم. حالا وب سرور ما روی دوتا پورت 8000 و 8001 به درخواست های ما گوش میده. کافیه آدرس localhost:8001/home رو باز کنید تا نتیجه رو ببینید. اگر روی یکی از تصاویری که میبینید کلیک کنید متوجه خواهید شد با اینکه ادرس با home شروع میشود اما تصاویر از مسیر درستی خوانده میشوند.

نمایش لیست فایل ها توسط وب سرور

در مثال های قبل اگر توی مسیری برید که وجود ندارد با صفحه 404 مواجه میشید. اما اگه مسیری رو برید که وجود داشته باشه ولی در آدرس شما, دقیقا فایل خاصی رو مشخص نکرده باشید با صفحه 403 access forbidden مواجهه میشوید.

article figures

ما میخوایم در حالتی که مسیر مورد نظر ما وجود داشت, لیست فایل ها و فولدر های درون اون مسیر به ما نمایش داده شود. برای اینکار کافیست autoindex را on کنیم.

server {
    listen 8002 default_server;

    location / {
        autoindex on;

        root /var/www/public;

        index index.html;
    }
}

در مثال بالا ما autoindex on رو اضافه کردیم که باعث میشه اگه کاربر به آدرسی بره که وجود داره, بجای 403 access forbidden لیست فایل ها و پوشه های موجود رو نشون بدیم.

article figures
نمایش لیست فایل ها و فولدرهای درون یک آدرس در صورتی که اون آدرس وجود داشته باشد

ریدایرکت کردن توسط وب سرور

هدایت کاربر از یک آدرس یا مسیر به آدرس یا مسیر دیگر را "ریدایرکت (redirect)" می‌نامند. 

برای ریدایرکت کردن میتونید از دستور return به همراه یک عدد و آدرس مورد نظر استفاده کرد. برای ریدایرکت کردن عددی که مشخص میکنید باید 3xx باشد (بزرگتر مساوی 300 و کمتر از 400) میتونید راجب HTTP redirect status code جستجو کنید و مطالعه کنید. هرکدام از کدها معنی خاصی دارند. اگه قرار است ریدارکت شما دائمی باشد بهتر است از 301 و اگر دائمی نیست بهتر است از 302 استفاده کنید.

server {
    listen 8003 default_server;

    location / {
        return 301 /home;
    }

    location /home {
        alias /var/www/public;

        index index.html;
    }
}

در مثال بالا یک redirect روی آدرس / مشخص کردیم. اگر شما هر آدرسی رو باز کنید که با /home شروع نشود, درخواست شما به /home ریدایرکت خواهد شد. برای اینکه بهتر متوجه بشید میتونید یکی از آدرس هایی که در زیر ذکر شده رو باز کنید و نتیجه رو ببینید:

http://localhost:8003/a-random-address/
http://localhost:8003/

http://127.0.0.1:8003/a-random-address/
http://127.0.0.1:8003/

گوش دادن به چندین پورت

اگه می‌خواید یه سرور راه بندازید که هم‌زمان روی چند پورت به درخواست‌ها جواب بده، دو راه دارید, یا پورت‌ها رو با ویرگول از هم جدا کنید و به صورت لیست بدید، یا برای هر پورت جداگانه یک بار دستور listen رو بنویسید.

server {
    listen 8009 default_server;
    listen 8010 default_server;

    location / {
        root /var/www/public;

        index index.html;
    }
}

برای مشخص کردن یک بازه از پورت‌ها، می‌توان از نماد خط تیره (-) استفاده کرد. در این روش، شماره پورت ابتدایی و انتهایی را با خط تیره از یکدیگر جدا می‌کنید. بدین ترتیب، پورت شروع، پورت پایان و تمامی پورت‌های مابین آن‌ها در بازه‌ مورد نظر قرار می‌گیرند.

server {
    listen 8004-8008 default_server;

    location / {
        root /var/www/public;

        index index.html;
    }
}

همچنین دو مثال قبلی رو میشه باهم ترکیب کرد. یعنی شما هم میتونید یک listen برای رنج پورت مورد نظر مشخص کنید و همچنین دوباره listen را برای یک پورت خاص دیگر تکرار کنید.

نمونه کد تمامی مثال هایی که در این قسمت داشتیم را میتونید همچنین در Github ببینید.


قسمت قبل: معماری و تنظیمات اولیه | Nginx from stratch

قسمت بعد: لود بالانس | Nginx from scratch


دیدگاه ها