طرح‌چه

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

4 روز پیش

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

برای استفاده از nginx ابتدا باید آن را نصب و راه اندازی کنید. روش نصب بر حسب اینکه از چه سیستم عاملی استفاده میکنید ممکن است متفاوت باشد.

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

  • به عنوان روش دوم در ویندوز میتونید از winget استفاده کنید. این ابزار یک پکیج منیجر هست و براتون نرم افزارهایی که میخواید رو نصب میکنه. کافیست winget رو از طریق Microsoft Store نصب کنید و سپس با توجه به مستندات nginx رو نصب کنید.

  • اگر از لینوکس (Linux) یا FreeBSD استفاده میکنید میتونید طبق مستندات nginx رو نصب و راه اندازی کنید.
  • توی MacOS میتونید از brew برای نصب استفاده کنید کافیست دستور را اجرا کنید.
  • روش پیشنهادی من استفاده از داکر (docker) است. برای اینکار میتونید ابتدا داکر را نصب کنید و سپس با استفاده از دستور زیر nginx رو اجرا کنید.

docker run --detach --rm --publish 80:80 nginx:stable

 اگر به عنوان مهندس نرم افزار یا برنامه نویس کار میکنید و با داکر آشنایی ندارید, الان فرصت خوبیه که اونو نصب کنید و ازش استفاده کنید.

  • اگه روی ویندوز هستین با استفاده از winget تقریبا هرچیزی رو میتونید نصب کنید. مثلا میتونید Docker رو با winget نصب کنید.

برای اطمینان از نصب, کافیه با استفاده از مرورگر خود, به یکی از ادرس های localhost یا 127.0.0.1 ‍ برید و باید با صفحه ای مانند تصویر زیر روبرو بشید.

localhost-nginx
صفحه ی پیش فرض nginx

نکته: در صورتی که از سیستم عامل ویندوز یا MacOS استفاده میکنید ممکن است nginx به صورت پیش فرض روی پورت 8080 صفحه ی بالا را نمایش دهد. بدین منظور تهه آدرس خودتون باید :8080 را وارد کنید. پس اگه ادرس بالا کار نکرد میتونید localhost:8080 یا 127.0.0.1:8080 را نیز امتحان کنید.

روی ویندوز Make رو نیز نصب کنید چون جلوتر ازش استفاده میکنیم. روی MacOS و Linux به صورت پیش فرض این ابزار موجود است. برای اطمینان از نصب میتونید دستور make -v رو اجرا کنید و باید ورژنی که نصب هست رو بهتون نشون بده.

GNU-make-version
GNU make version

فایل ها و مسیرهای مهم

  • /etc/nginx/ : به صورت پیش فرض فایل های تنظیمات nginx در این مسیر قرار دارند.
  • /etc/nginx/nginx.conf : این فایل به صورت پیش فرض نقطه ی شروعی برای لود کردن باقی تنظیمات است. یکسری تنظیمات اولیه مربوط به وب سرورهای http و همچنین تنظیمات مربوط به نوشتن لاگ ها درون این فایل قرار دارد و سپس این فایل باقی تنظیمات رو از مسیر /etc/nginx/conf.d/ لود میکند.

  • /etc/nginx/conf.d/ : به صورت پیش فرض هر فایلی که با پسوند conf درون این دایرکتوری بسازید به عنوان تنظیمات لود میشود.

  • /var/log/nginx/ : در این مسیر دو فایل access.log و error.log رو میتونیم ببینیم که لاگ های دسترسی (access logs) و همچنین لاگ های مربوط به خطاها (error logs) درون این فایل ها ذخیره میشوند.

کنسول کمندهای پایه

  • nginx -h : این دستور حکم راهنما یا help را دارد. با استفاده از اون میتونید با لیست باقی دستورات و نحوه استفاده ازشون آشنا بشید.
article figures
  • nginx -v : این دستور ورژن nginx شما رو بهتون نشون میده.
  • nginx -V : این دستور علاوه بر ورژن nginx اطلاعات بیشتری راجب تنظیمات و ماژول های nginx به شما میدهد.
article figures
  • nginx -t : این دستور صحت تنظیمات شما که به صورت پیش فرض در مسیر /etc/nginx/ هست رو چک میکند و نتیجه را به شما اعلام میکند.
article figures
  • nginx -T : این دستور همانند دستور قبل هست با این تفاوت که تنظیماتی که بررسی شدن رو در صفحه چاپ میکند.
  • nginx -s signal : با استفاده از این دستور میتونید یکسری سیگنال به nginx ارسال کنید. سیگنال میتواند stop , quit , reload یا reopen باشد.
    • stop باعث توقف آنی nginx میشود.
    • quit باعث میشود تا nginx ابتدا درخواست هایی که دریافت کرده است را اجرا کند و سپس متوقف شود.
    • reload باعث میشود تا nginx دوباره تنظیمات را بخواند و خود را برحسب آنها تنظیم کند.
    • reopen باعث میشود تا nginx فایل های لاگ را دوباره باز کند.

در مثال زیر هرکدام از سیگنال ها رو به صورت جداگانه به nginx ارسال کرده ایم:

nginx -s stop
nginx -s quit
nginx -s reload
nginx -s reopen

ایجاد وب سرور برای لود فایل های استاتیک

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

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

server {
    listen 8000 default_server;

    location / {
        root /var/www/public;

        index index.html;
    }
}

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

در دستورات بالا اولین خط 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


دیدگاه ها