در این راهنما با روش ساخت یک وب‌اپلیکیشن پایتون با کمک گرفتن از میکرو فریمورک Flask روی اوبونتو 18.04 آشنا می‌شویم. بخش عمده این مقاله به توضیح روش راه‌اندازی سرور اپلیکیشن uWSGI و شیوه اجرای اپلیکیشن و پیکربندی Nginx برای عملکرد به عنوان یک پراکسی معکوس فرانت‌اند اختصاص یافته است. بنابراین با ما همراه باشید تا با روش عرضه اپلیکیشن Flask با uWSGI و Nginx آشنا شوید.

پیش‌نیازها

پیش از آن که شروع به مطالعه این راهنما بکنید، باید موارد زیر را آماده کرده باشید.

  • یک سرور که اوبونتو 18.04 روی آن نصب شده باشد و دارای یک کاربر غیر root با دسترسی‌های Sudo باشد. برای کسب اطلاعات بیشتر در این خصوص می‌توانید از این مطلب کمک بگیرید.
  • سپس باید وب‌سرور Nginx را روی سرور نصب کنید. به این منظور می‌توانید از گام یکم این راهنما کمک بگیرید.
  • همچنین باید یک نام دامنه داشته باشید که به سرور شما اشاره کند. برای این که با روش تنظیم DNS و نام‌های دامنه آشنا شوید، می‌توانید از این راهنمای مجله فرادرس استفاده کنید. در هر حال باید دو مورد زیر را تنظیم نمایید:
    • یک رکورد A به صورت your_domain که به نشانی IP عمومی سرور اشاره کند.
    • یک رکورد A به صورت www.your_domain که به نشانی IP عمومی سرور اشاره کند.
  • همچنین شما می‌بایست با uWSGI، سرور اپلیکیشن و مشخصات WSGI آشنا باشید.

گام اول: نصب کامپوننت‌ها از ریپازیتوری‌های اوبونتو

نخستین گام در این راهنما، نصب همه بخش‌های نرم‌افزاری لازم با استفاده از ریپازیتوری‌های اوبونتو است. ابتدا pip را نصب می‌کنیم. pip ابزار مدیریت بسته در پایتون است که امکان نصب و مدیریت پکیج‌های مختلف پایتون را فراهم می‌سازد. همچنین فایل‌های توسعه پایتون را که برای بیلد کردن uWSGI لازم هستند را نیز دریافت می‌کنیم.

ابتدا باید ایندکس پکیج لوکال را به‌روزرسانی کرده و پکیج‌هایی که امکان بیلد کردن محیط پایتون را فراهم می‌سازند نصب کنیم. این موارد شامل python3-pip و همچنین چند پکیج دیگر و ابزارهای توسعه است که برای ساخت یک محیط برنامه‌نویسی پایدار مورد نیاز هستند:

اکنون که این پکیج‌ها را گرد هم آوردیم، می‌توانیم اقدام به ساخت محیط مجازی برای پروژه خود بکنیم.

عرضه اپلیکیشن Flask با uWSGI و Nginx

گام دوم: ایجاد محیط مجازی پایتون

در گام بعدی یک محیط مجازی راه‌اندازی می‌کنیم تا اپلیکیشن فلسک خودمان را از دیگر فایل‌های پایتون روی سیستم مجزا سازیم. کار خود را با نصب کردن پکیج python3-venv آغاز می‌کنیم که ماژول venv را نصب می‌کند.

سپس یک دایرکتوری والد برای پروژه Flask ایجاد می‌کنیم. پس از ساختن دایرکتوری، به آن مراجعه می‌کنیم:

در ادامه با استفاده از دستور زیر، یک محیط مجازی برای ذخیره الزامات پایتونی پروژه فلسک ایجاد می‌کنیم:

دستور فوق یک کپی لوکال از پایتون و pip در یک دایرکتوری به نام myprojectenv در داخل دایرکتوری پروژه نصب می‌کند.

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

در این زمان اعلان تغییر می‌یابد تا نشان دهد که شما هم اکنون در حال فعالیت درون محیط مجازی هستید. اعلان اکنون باید به صورت زیر در آمده باشد:

گام سوم: راه‌اندازی اپلیکیشن فلسک

اکنون که داخل محیط مجازی هستیم، می‌توانیم فلسک را با استفاده از uWSGI نصب کرده و شروع به طراحی اپلیکیشن بکنیم. ابتدا باید wheel را با وهله لوکال pip نصب کنیم تا مطمئن شویم که پکیج‌ها حتی در صورت از دست رفتن آرشیو‌های wheel نصب می‌شوند:

  • نکته: صرف نظر از این که از چه نسخه‌ای از پایتون استفاده می‌کنید، هنگامی که محیط مجازی فعال شد، باید از دستور pip و نه pip3 استفاده کنید.

در ادامه Flask و uWSGI را نصب می‌کنیم:

ساخت یک اپلیکیشن ساده

اکنون که به فلسک دسترسی داریم، می‌توانیم دست به ساخت یک اپلیکیشن ساده بزنیم. فلسک یک میکرو فریمورک است و شامل هیچ کدام از ابزارهایی که یک فریمورک کامل ممکن است داشته باشد، نیست. در واقع فلسک به صورت یک ماژول عرضه شده که می‌تواند داخل پروژه‌ها ایمپورت شده و یک وب‌اپلیکیشن را مقداردهی کند.

البته شما می‌توانید یک وب‌اپلیکیشن پیچیده نیز طراحی کنید، اما ما در این راهنما یک اپلیکیشن ساده فلسک در یک فایل منفرد به نام myproject.py ایجاد می‌کنیم.

کد اپلیکیشن در این فایل قرار دارد. این فایل فلسک را ایمپورت کرده و یک وهله از یک پروژه فلسک ایجاد می‌کند. شما می‌توانید از این برای تعریف تابع‌هایی استفاده کنید که در زمان درخواست یک مسیر خاص، اجرا شوند:

  • فایل ~/myproject/myproject.py
این فایل در اساس محتوایی که در زمان دسترسی به دامنه ریشه نمایش می‌یابد را تعیین می‌کند. زمانی که کارتان پایان یافت، فایل را ذخیره کرده و خارج شوید.

اگر از راهنمایی راه‌اندازی اولیه سرور که در ابتدای راهنما معرفی کردیم، پیروی کرده باشید، اکنون باید فایروال UFW برایتان فعال شده باشد. اما برای تست اپلیکیشن باید امکان دسترسی به پورت 5000 را باز کنید:

اکنون می‌توانید اپلیکیشن فلسک را با وارد کردن دستور زیر تست کنید:

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

اکنون نشانی آی پی سرور و در انتها:5000 را در مرورگر وب وارد کنید.

تا پیامی مانند زیر مشاهده کنید:

زمانی که کارتان پایان یافت، کلیدهای Ctrl+C را در پنجره ترمینال بگیرید تا سرور توسعه فلسک متوقف شود.

ایجاد نقطه ورود WSGI

در ادامه باید فایلی بسازیم که به عنوان نقطه ورود برای اپلیکیشن استفاده می‌شود. این نقطه ورود به سرور uWSGI اعلام می‌کند که چطور با آن تعامل پیدا کند. نام فایل را wsgi.py می‌گذاریم:

در این فایل، یک وهله از فلسک را از اپلیکیشن ایمپورت و سپس اجرا می‌کنیم:

فایل را ذخیره کرده و خارج شوید.

گام چهارم: پیکربندی uWSGI

اکنون اپلیکیشن ما با یک نقطه ورود نوشته و پیکربندی شده است. در ادامه به پیکربندی uWSGI می‌پردازیم.

تست سرور uWSGI

در آغاز یک تست از سرور uWSGI می‌گیریم تا از عملکرد صحیح آن مطمئن شویم. به این منظور کافی است نام نقطه ورود را به آن ارسال کنیم. این نام شامل نام ماژول (منهای پسوند py.) به علاوه نام قابل فراخوانی درون اپلیکیشن است. در این مورد از نام wsgi:app استفاده می‌کنیم.

همچنین باید سوکت را تعیین کنیم تا به صورت یک اینترفیس عمومی عرضه شود. همچنین باید پروتکل مشخص شود تا از HTTP به جای پروتکل باینری uwsgi استفاده کند. شماره پورت نیز همان 5000 خواهد بود که قبلاً باز کرده‌ایم:

اکنون اگر نشانی آی پی را به همراه شماره پورت 5000: در مرورگر وب وارد کنید:

خروجی اپلیکیشن را به صورت زیر مشاهده خواهید کرد:

زمانی که از کارکرد صحیح اپلیکیشن مطمئن شدید، کلیدهای Ctrl+C را بگیرید تا پنجره ترمینال بسته شود. اکنون کارمان با محیط مجازی پایان یافته است و می‌توانیم آن را غیر فعال کنیم.

هر دستور پایتون از این به بعد از محیط پایتون سیستمی استفاده خواهد کرد.

ساخت فایل پیکربندی uWSGI

در بخش قبل تست کردیم و دیدیم که سرور uWSGI می‌تواند اپلیکیشن را عرضه کند، اما در نهایت می‌خواهیم که چیز پایداری برای بلندمدت در اختیار داشته باشیم. به این منظور یک فایل پیکربندی uWSGI با گزینه‌های مرتبط ایجاد می‌کنیم. این فایل را در دایرکتوری پروژه قرار داده و نام آن را myproject.ini می‌گذاریم.

درون این فایل ابتدا هدر [uwsgi] را قرار می‌دهیم تا uWSGI بداند که باید از این تنظیمات استفاده کند. سپس دو چیز را تعیین می‌کنیم که اولی خود ماژول است که با اشاره به نام فایل wsgi.py منهای پسوند و سپس نام قابل فراخوانی درون فایل یعنی app مشخص می‌شود:

سپس به uWSGI اعلام می‌کنیم که در حالت master آغاز شود و پنج پردازش ورکر را برای عرضه درخواست‌های واقعی اجرا کند:

زمانی که مشغول تست بودیم، uWSGI را روی پورت شبکه عرضه کردیم. با این حال در ادامه می‌خواهیم از وب‌سرور Nginx برای مدیریت اتصال‌های واقعی از سمت کلاینت بهره بگیریم که در ادامه درخواست‌ها را به Nginx هدایت می‌کند. از آنجا که این کامپوننت‌ها روی رایانه یکسانی فعالیت می‌کنند، استفاده از یک سوکت یونیکس ترجیح بیشتری دارد، زیرا سریع‌تر و امن‌تر است. نام این سوکت را myproject.sock گذاشته و آن را در این دایرکتوری قرار می‌دهیم.

همچنین مجوزهای روی سوکت را تغییر می‌دهیم. ما از این پس مالکیت پردازش uWSGI را به گروه Nginx خواهیم داد و از این رو باید مطمئن شویم که مالک گروه سوکت می‌تواند اطلاعات را از آن خوانده و بنویسد. همچنین زمانی که پردازش با افزودن گزینه vacuum متوقف شود، آن را پاک‌سازی می‌کنیم.

آخرین کاری که باید انجام دهیم، تنظیم گزینه die-on-term است این تنظیمات به ما کمک می‌کند که مطمئن شویم سیستم init و uWSGI تصورات یکسانی در مورد معنای هر یک از سیگنال‌ها دارند. تنظیم این مورد موجب همسو شدن دو کامپوننت سیستمی می‌شود و رفتار مورد نظر ما را پیاده‌سازی خواهد کرد:

ممکن است متوجه شده باشید که برخلاف حالتی که در خط فرمان داشتیم، این بار هیچ پورتی را تعیین نکردیم. دلیل این امر آن است که uWSGI به طور پیش‌فرض از طریق پروتکل uWSGI ارتباط می‌گیرد که یک پروتکل سریع باینری است و برای ارتباط با سرورها طراحی شده است. Nginx می‌توانید به صورت نیتیو با این پروتکل صحبت کند، از این رو بهتر است که به جای الزام به استفاده از HTTP از آن بهره بگیریم. در نهایت فایل را ذخیره کرده و خارج شوید.

عرضه اپلیکیشن Flask با uWSGI و Nginx

گام پنجم: ایجاد فایل systemd Unit

در ادامه فایل یونیت سرویس systemd را ایجاد می‌کنیم. ساخت چنین فایلی موجب می‌شود که سیستم init اوبونتو بتواند به طور خودکار uWSGI را آغاز کرده و اپلیکیشن فلسک را در زمان بوت شدن سرور عرضه کند.

یک فایل یونیت با پسوند ‎.service در مسیر /etc/systemd/system ایجاد می‌کنیم:

درون فایل کار خود را با سکشن [Unit] آغاز می‌کنیم که برای تعیین متادیتا و وابستگی‌ها استفاده می‌شود. در این بخش یک توضیح از این سرویس نوشته و به سیستم init اعلام می‌کنیم که تنها پس از آن که به هدف شبکه‌بندی رسید، آن را آغاز کند:

سپس سکشن [Service] را باز می‌کنیم. در این بخش کاربر و گروهی که پردازش تحت آن اجرا خواهد شد را مشخص می‌کنیم. در ادامه مالکیت پردازش را به حساب کاربری معمولی خود می‌دهیم، زیرا مالکیت همه فایل‌های مرتبط با آن است. همچنین مالکیت گروه را به گروه www-data می‌دهیم تا Nginx بتواند به آسانی با پردازش‌های uWSGI ارتباط بگیرد. به خاطر داشته باشید که نام کاربری را با username خودتان عوض کنید:

در ادامه دایرکتوری کاری را نگاشت کرده و متغیر محیطی PATH را طوری تنظیم می‌کنیم که سیستم init بداند فایل‌های اجرایی پردازش درون محیط مجازی قرار دارند. همچنین دستور مورد نظر برای آغاز سرویس را نیز مشخص می‌کنیم. Systemd الزام می‌کند که مسیر کامل به فایل اجزایی uWSGI را تعیین کنیم که درون محیط مجازی نصب شده است. به این منظور نام فایل پیکربندی ‎.ini را که در دایرکتوری پروژه ایجاد کردیم را ارسال می‌کنیم.

به خاطر داشته باشید که باید username و مسیرهای پروژه را با اطلاعات خودتان عوض کنید:

در نهایت باید سکشن [Install] را اضافه کنیم. این بخش به systemd اعلام می‌کند که در صورت فعال‌سازی آغاز شدن در زمان بوت باید این سرویس را به چه چیزی لینک کند. ما می‌خواهیم این سرویس زمانی که سیستم چندکاربره معمولی آغاز و اجرا شد، شروع به کار کند.

به این ترتیب فایل سرویس systemd پایان یافته است. اکنون می‌توانید فایل را بسته و خارج شوید. در ادامه می‌توانیم سرویس systemd را آغاز کرده و آن را طوری فعال کنیم که در زمان بوت شدن بتواند آغاز شود.

اینک وضعیت آن را بررسی می‌کنیم:

اکنون باید خروجی زیر را ببینید:

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

گام ششم: پیکربندی Nginx برای پراکسی کردن درخواست‌ها

اکنون سرور اپلیکیشن uWSGI ما باید آغاز شده و در حال اجرا و منتظر دریافت درخواست‌ها روی فایل سوکت در دایرکتوری پروژه باشد. در ادامه وب‌سرور Nginx را طوری پیکربندی می‌کنیم تا درخواست‌های وب را با استفاده از پروتکل uwsgi به این سوکت ارسال کند.

کار خود را با ایجاد فایل پیکربندی بلوک سرور جدید در دایرکتوری sites-available انجین‌ایکس آغاز می‌کنیم. نام این فایل را myproject می‌گذاریم تا با بقیه بخش‌های راهنما هماهنگ باشد.

یک بلوک سرور جدید ایجاد می‌کنیم تا به انجین ایکس اعلام کنیم که روش پورت پیش‌فرض 80 گوش کند. همچنین از آن برای تعیین بلوک شنیدن درخواست‌ها روی نام دامنه سرور استفاده می‌کنیم:

در ادامه یک بلوک لوکیشن اضافه می‌کنیم که با هر درخواست تطبیق یابد. درون این بلوک، فایل uwsgi_params را قرار می‌دهیم که برخی پارامترهای عمومی uWSGI که باید تنظیم شوند را مشخص می‌سازد. در ادامه درخواست‌ها را به سوکت ارسال کنیم که با دایرکتیو uwsgi_pass تعریف شده است.

در نهایت فایل را ذخیره کرده و ببندید.

برای فعال‌سازی پیکربندی بلوک سرور Nginx که هم‌اینک ایجاد کردیم، باید فایل را به دایرکتوری sites-enabled پیوند دهیم:

اینک که فایل در دایرکتوری قرار دارد، می‌توانیم خطاهای سینتکس را با وارد کردن دستور زیر تست کنیم:

اگر دستور فوق بدون هیچ مشکل بازگشت یابد، می‌توانید پردازش انجین‌ایکس را ری‌استارت کنید تا پیکربندی‌های جدید را بخواند:

در نهایت، دوباره فایروال را تنظیم می‌کنیم. از آنجا که دیگر نیازی به دسترسی از طریق پورت 5000 نداریم، می‌توانیم این قاعده را حذف کنیم. در ادامه امکان دسترسی به سرور NginX را فعال می‌کنیم.

اکنون می‌توانید در مرورگر وب خود به نام دامنه مراجعه کنید:

و خروجی اپلیکیشن را به صورت زیر مشاهده کنید:

اگر با هر نوع خطایی مواجه شدید، یکی از موارد زیر را بررسی کنید:

  • برای بررسی خطاهای Nginx به این مسیر بروید: sudo less /var/log/nginx/error.log
  • برای دسترسی به لاگ‌های Nginx به این مسیر بروید: sudo less /var/log/nginx/access.log
  • برای بررسی لاگ‌های پردازش Nginx به این مسیر بروید: sudo journalctl -u nginx
  • برای بررسی لاگ‌های اپلیکیشن فلسک به این مسیر بروید: sudo journalctl -u myproject

گام هفتم: امن‌سازی اپلیکیشن

برای اطمینان یافتن از این که ترافیک سرور امن باقی می‌ماند، یک گواهی SSL برای دامنه خود می‌گیریم. به این منظر روش‌های مختلفی وجود دارد، اما آسان‌ترین راه که هزینه‌ای هم در برندارد استفاده از مرجع گواهینامه‌های امنیتی Let’s Encrypt است. برای کسب اطلاعات بیشتر در این خصوص می‌توانید از این مطلب استفاده کنید:

ابتدا ریپازیتوری Certbot اوبونتو را اضافه می‌کنیم:

برای پذیرش باید اینتر را بزنید. سپس پکیج Certbot انجین‌ایکس را با apt نصب کنید:

Certbot روش‌های مختلفی برای به دست آوردن گواهینامه SSL از طریق افزونه‌ها ارائه کرده است. افزونه Nginx وظیفه پیکربندی وب‌سرور Nginx و بارگذاری مجدد پیکربندی را در موارد نیاز بر عهده دارد. برای استفاده از این افزونه باید دستور زیر را وارد کنید:

دستور فوق certbot را با افزونه –nginx اجرا می‌کند. شما می‌توانید از گزینه d- برای تعیین نام‌هایی که گواهینامه برای آن‌ها معتبر خواهد بود بهره بگیرید.

اگر نخستین بار است که certbot را اجرا می‌کنید، از شما خواسته می‌شود که یک نشانی ایمیل وارد کرده و موافقت خود را با شرایط سرویس اعلام کنید. در ادامه certbot با سرور Let’s Encrypt ارتباط گرفته و یک چالش برای تأیید کنترل شما روی دامنه‌ای که تقاضای گواهینامه برایش دارید اجرا می‌کند.

اگر این چالش موفق باشد، certbot در مورد شیوه پیکربندی تنظیمات HTTPS سؤالاتی از شما می‌پرسد.

گزینه‌های مورد نظر خود را انتخاب کرده و اینتر را بزنید. در ادامه پیکربندی به‌روزرسانی می‌شود و Nginx دوباره بارگذاری خواهد شد تا تنظیمات جدید اعمال شوند. در نهایت certbot پیامی نمایش می‌دهد که نشان‌دهنده موفقیت‌آمیز بودن فرایند و محل ذخیره شدن گواهینامه‌ها است.

اگر دستورالعمل‌های نصب Nginx در بخش پیش‌نیازهای این راهنما را به درستی پیگیری کرده باشید، دیگر نیازی به صدور مجوز تکراری برای پروفایل HTTP نخواهید داشت.

برای بررسی پیکربندی، یک بار دیگر به دامنه سر می‌زنیم ولی این بار از پروتکل Https://‎ استفاده می‌کنیم:

اکنون باید مجدداً خروجی اپلیکیشن خود را به همراه نشانگر امنیتی مرورگر که نشان می‌دهد وب‌سایت مورد نظر ایمن است، ببینید.

سخن پایانی: عرضه اپلیکیشن Flask با uWSGI و Nginx

در این راهنمای عرضه اپلیکیشن Flask با uWSGI و Nginx یک اپلیکیشن ساده و امن فلسک را درون محیط مجازی پایتون ایجاد کردیم. در این مسیر یک نقطه ورود WSGI ساختیم که اجازه می‌دهد هر سرور اپلیکیشن با قابلیت WSGI بتواند با آن تعامل یابد و سپس سرور اپلیکیشن uWSGI را برای عرضه این قابلیت پیکربندی کردیم. در ادامه یک فایل سرویس systemd ساختیم تا در زمان بوت شدن سیستم، سرور اپلیکیشن را به طور خودکار راه‌اندازی کند. همچنین یک بلوک سرور Nginx ساختیم که ترافیک کلاینت را به سرور اپلیکیشن هدایت کرده و درخواست‌های بیرونی و ترافیک امن را به کمک Let’s Encrypt به سرور اپلیکیشن رله می‌کند.

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

اگر این مطلب برای شما مفید بوده است، آموزش‌ها و مطالب زیر نیز به شما پیشنهاد می‌شوند:

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

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

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