کار با فلسک و داکر

ترجمه و تالیف : ارسطو عباسی
تاریخ انتشار : 19 اسفند 98
خواندن در 4 دقیقه
دسته بندی ها : پایتون

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

ابتدای کار ما قصد داریم یک اپلیکیشن Hello World ساده را با استفاده از فلسک ایجاد کرده و آن را با استفاده از سرور Gunicorn میزبانی کنیم. البته خود فلسک نیز قابلیت‌های داخلی برای میزبانی شدن را دارد اما استفاده از این قابلیت برای تولید محصول و ساخت یک اپلیکیشن حرفه‌ای مناسب نیست. به همین دلیل است که ما قصد داریم تا از WSGI و Gunicorn استفاده کنیم. (ساده و مطمئن)

ابتدا؛ داکر چیست؟

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

 برای درک بهتر این موضوع می‌توانید مقاله سه قسمتی ما در ارتباط با تفاوت داکر و ماشین مجازی را مطالعه کنید.

پیاده‌سازی اپلیکیشن

ابتدای کار یک دایرکتوری جدید ایجاد کرده و وارد آن شوید. قرار است که در این دایرکتوری اپلیکیشن فلسک را ایجاد کنیم. 

mkdir flask-app
cd flask-app

بعد از آن یک فایل جدید پایتونی را ایجاد کرده و کدهای زیر را در آن قرار دهید:

from src import app
from flask import Flask, jsonify

@app.route('/')
def index():
    return jsonify(message="hello, world!")

کار با فلسک و داکر

تمام کاری که این برنامه می‌کند این است که با فراخوانی آن در مرورگر یک داده JSON را برمی‌گرداند. در حقیقت می‌توان گفت که به صورتی یک API را ایجاد کرده‌ایم.

در کنار این فایل ما به دو فایل دیگر نیاز داریم. یک فایل برای ایجاد نمونه‌ای از اپلیکیشن که برای ساخت آن از فایل __init__.py استفاده می‌کنیم و یک فایل requirements.txt که برای نمایش ماژول‌های مورد نیاز آن را خواهیم ساخت. 

فایل init را با محتوای زیر پر کنید:

from flask import Flask
app = Flask(__name__)

from .server import *

و فایل بعدی را با محتوای زیر:

flask
gunicorn

نکته: منظور از .server در کدهای init نام فایلی است که محتوای اصلی اپلیکیشن را در آن قرار داده‌ایم. می‌توانید ساختار کلی این پروژه را در تصویر زیر نیز مشاهده کنید:

کار با فلسک و داکر

حال برای اجرا کردن سرور ابتدا مطمئن شوید که ماژول‌های مورد نیاز روی سیستم شما نصب است. برای انجام این کار می‌توانید دستور زیر را در ترمینال وارد کنید:

pip3 install -r src/requirements.txt

و حال قدم بعدی اجرای اپلیکیشن از طریق gunicorn است که برای آن دستور زیر را وارد کنید:

gunicorn src:app

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

کار با فلسک و داکر

پیکربندی سرور Gunicorn

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

برای اینکه به درستی این وب سرور را کانفیگ بکنیم یک دایرکتوری جدید با نام conf ایجاد کرده و در داخل آن فایل gunicorn_config.py را بسازید. حال کدهای زیر را در داخل این فایل قرار دهید:

import multiprocessing

bind = "0.0.0.0:8000"
workers = multiprocessing.cpu_count() * 2 + 1
accesslog = "-" # STDOUT
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
loglevel = "debug"
capture_output = True
enable_stdio_inheritance = True

منظور از bind این است که وب سرور را به یک پورت خاص متصل کرده و در تمام رابط‌ها از آن استفاده کند. 

منظور از workers تعداد نخ‌های worker هستند که درخواست‌ها را اجرا می‌کنند.

منظور از access_log_format نوشتن Log با قالب داده شده است.

برای اطلاعات بیشتر در ارتباط با توانایی‌های این تکنولوژی (gunicorn) می‌توانید این لینک را مطالعه کنید. 

داکرایز کردن!

حال که اپلیکیشن و وب سرور ما به درستی کار می‌کند نیاز است تا همه چیز را در داخل یک کانتینر داکر قرار دهیم. برای انجام چنین کاری نیاز است تا یک Dockerfile را ایجاد کنیم.

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

فایل داکر ما به صورت زیر است:

# python runtime
FROM python:3.6.5-alpine

# working directory
WORKDIR /app

# copy current directory into the container
ADD . /app

# install requirements
RUN pip3 install -r src/requirements.txt

# make port 8000 available to the world outside
EXPOSE 8000

CMD ["gunicorn", "--config", "./conf/gunicorn_conf.py", "src:app"]
  • در خط ابتدای این سند ما شاهد دستور FROM هستیم که در‌واقع به ما کمک می‌کند تا از یک image پایه‌ای در فایل داکر استفاده کنیم. در این مثال ما از image مربوط به python:3.6.5-alpine استفاده کرده‌ایم. Alpine یک توزیع کوچک لینوکسی (در حدل ۵ مگابایت) است. از آنجایی که این توزیع کوچک است بیشتر اوقات در اپلیکیشن‌های مبتنی بر داکر استفاده می‌شود. به صورت کوتاه ما در این دستور در حال استفاده از محیط لینوکسی همراه با پایتون نسخه ۳.۶.۵ برای اجرا کردن اپلیکیشن‌مان هستیم.
  • در خط سوم ما یک WORKDIR را با نام app ایجاد کرده‌ایم.
  • در خط بعدی تمام چیزهایی که در داخل دایرکتوری کنونی (دایرکتوری که پروژه در آن قرار دارد) را در داخل دایرکتوری app قرار داده‌ایم.
  • خط بعدی برای نصب نیازمندی‌های اپلیکیشن استفاده می‌شود.
  • خط بعدی برای تعریف پورت اپلیکیشن استفاده می‌شود.
  • و در خط پایانی یکسری توکن را قرار داده‌ایم که به ما کمک می‌کند تا سرور Gunicorn را با استفاده از فایل کانفیگ اجرا کنیم.

همه چیز آماده اجرا است!

حال ما یک Dockerfile را در اختیار داریم، تنها گزینه دیگری که به آن نیاز داریم image مربوط به Dockerfile است. بعد از این ما قابلیت آن را خواهیم داشت که image خود را اجرا کنیم.

کار با فلسک و داکر

ساختار فایلی این پروژه باید به صورت تصویر بالا باشد. در نظر داشته باشید که فایل Dockerfile خارج از دایرکتوری src است. 

حال همانطور که گفته شد نیاز است تا یک docker image را ایجاد کنیم. برای انجام این کار دستورات زیر را اجرا نمایید:

$ docker build -t helloworld 
$ docker run -p 80:8000 helloworld
  • دستور ابتدایی فایل image مورد نظر ما را ایجاد می‌کند. پرچم -t نیز به image ما یک تگ می‌دهد.
  • دستور بعدی نیز برای اجرا کردن docker image استفاده می‌شود.

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

کار با فلسک و داکر

برای مشاهده لیستی از کانتینرهای فعال می‌توانیم از دستور docker ps استفاده کنیم.

کار با فلسک و داکر

دیپلوی کردن

حال که ما یک Docker image را در اختیار داریم باید سراغ مرحله بعد یعنی دیپلوی کردن برویم. حال شاید از خودتان بپرسید که به چه صورتی می‌توان این اپلیکیشن را روی یک محیط ابری مانند AWS EC2 یا هر سرویس دیگری دیپلوی کنیم؟ راه‌حل این کار استفاده از Docker Hub است.

Docker Hub

ابتدای کار نیاز است تا image مورد نظرمان را در public registry مربوط به Docker Hub قرار دهیم. از اینجا می‌توانیم image را به جاهای دیگر ارسال کنیم.

برای انجام این کار ابتدا یک اکانت جدید در Docker Hub ایجاد کرده و یک مخزن جدید ایجاد کنید. در زیر می‌توانید شیوه ساخت یک مخزن جدید را مشاهده کنید:

 مرحله بعدی نیاز است تا image خود را به صورت زیر push کنیم:

$ docker login
$ docker tag helloworld <username>/<repository-name>

حال می‌توان این image را با استفاده از دستور docker pull به هر سرویس ابری انتقال داد.

مثال: داکر روی Linux Box

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

کار با فلسک و داکر

$ docker run <username>/<repository-name>

داکر در این حالت به صورت خودکار image را دریافت کرده و روی سرور اجرا می‌کند.

در پایان

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

منبع

گردآوری و تالیف ارسطو عباسی

من ارسطو‌ام :) کافی نیست؟! :)