پیاده سازی Django و Celery در Hamravesh

1402/05/26 | 591 |
django

در این آموزش به بررسی نحوه پیاده سازی پروژه های جنگو به همراه Celery و background tasks و redis در پلتفرم همروش خواهیم پرداخت. و دو ساختار worker و beat را برای پروژه فعلی پیاده سازی خواهیم کرد.

برای درک بهتر نحوه پیاده سازی همراه با توضیحات درج شده می توانید به ویدئو زیر برای یادگیری نگاهی بیاندازید.

 

 

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

AliBigdeli/Django-Hamravesh-Docker-Celery-Template: a brief example of how to use django docker app with celery in hamravesh and local (github.com)

نکته: فرض می شود که شما پروژه ای آماده دارید و صرفا می خواهید این پروژه را به پلتفرم همروش منتثل نمایید.

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

  1.  آماده سازی پروژه در محیط Local
  2. آماده سازی دیتابیس در هم روش
  3. آماده سازی redis در هم روش
  4. پیاده سازی django
    1. ساحت اپ backend
    2. ساخت اپ Wokrer
    3. ساخت اپ Beat

آماده سازی پروژه فعلی

قبل از آنکه بخواهید پروژه خود را وارد پلتفرم همروش نمایید می بایست بعضی ساختار ها را در پروژه خود اعمال کنید که تا بتوان از طریق این سرویس پروژه شما قابلیت اجرا داشته باشد. از جمله اماده سازی ها می توان به داشتن Dockerfile مربوطه برای پیاده سازی پروژه Django و کتابخانه های لازم جهت سرو کردن و سطح دسترسی های جنگو و Requirements  به همراه اضافه کردن تنظیمات مورد نیاز به بخش settings اشاره کرد.

نکته: برای تمیز تر شدن پیاده سازی پروژه خود را به داخل یک پوشه دیگر مانند core منتقل نمایید

ساخت requirements.txt

برای اینکه بتوانید ماژول های مورد نیاز را در داکر نصب نمایید بهتر است که یک فایل requirements.txt در آدرس root پروژه خود ایجاد نمایید. سپس ماژول های مورد نیاز خود برای پروژه را درج کنین، اما یک ماژول می بایست حتما در پروژه شما وجود داشته باشد و آن هم gunicorn و whitenoise برای پاسخدهی به سدرخواست ها و serve کردن فایل های استاتیک پروژه است. همراه با اضافه کردن این ماژول ها می بایست تنظیمات مربوطه را نیز به پروژه خود اضافه نمایید. برای سادگی عملکرد به نمونه زیر دقت نمایید:

فایل requirements.txt

# general  modules
django >3.2,<3.3

# env controls
python-decouple


# deployment module
gunicorn
whitenoise


# database client
psycopg2-binary

# background proccess and cache
celery[redis]
redis
django-redis

# your other modules goes here

تنظیمات مربوط به whitenoise در settings.py

....

if config("ENABLE_WHITENOISE", cast=bool, default=False):
    # Insert Whitenoise Middleware.
    MIDDLEWARE += [
        "whitenoise.middleware.WhiteNoiseMiddleware",
    ]
    STATICFILES_STORAGE = 'whitenoise.storage.StaticFilesStorage'

....


نکته: برای راحتی کار با پروژه و فعال و غیر فعال کردن بعضی المان ها من از environment ها برای تاثیر گذاری در پروژه استفاده می کنم که ماژولpython-decouple برای همین کار است و شما می توانید آن را جایگزین ماژول محبوب خود کنید.

برای اینکه Celery در پروژه فعال شود نیاز است که در تنظیمات پروژه دو تغییر ایجاد نمایید:

ساخت فایل celery.py

# core/core/celery.py


import os

from celery import Celery
from celery.schedules import crontab

# Set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

app = Celery("core")

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object("django.conf:settings", namespace="CELERY")

# Load task modules from all registered Django apps.
app.autodiscover_tasks()

اضافه کردن تنظیمات خواندن و فعال سازی celery در init پروژه

from .celery import app as celery_app

__all__ = ['celery_app']

به یاد داشته باشید که تمام بخش های دیگر پروژه که نیاز است که از بیرون اعمال شوند را به حالت environment در آورید. مثل تنظیمات دیتابیس، ایمیل، secret_key و allowed_host و اصولا هر چیزی که نیاز است. نمونه زیر را در نظر بگیرید:

# secret key 
SECRET_KEY = config("SECRET_KEY", default="test")

# debug settings
DEBUG = config("DEBUG", cast=bool, default=True)


# allowed hosts
ALLOWED_HOSTS = config(
    "ALLOWED_HOSTS",
    cast=lambda v: [s.strip() for s in v.split(",")],
    default="*",
)

# database configs
DATABASES = {
    "default": {
        "ENGINE": config("PGDB_ENGINE", default="django.db.backends.postgresql"),
        "NAME": config("PGDB_NAME", default="postgres"),
        "USER": config("PGDB_USER", default="postgres"),
        "PASSWORD": config("PGDB_PASS", default="postgres"),
        "HOST": config("PGDB_HOST", default="db"),
        "PORT": config("PGDB_PORT", cast=int, default=5432),
    }
}

# email configs
EMAIL_BACKEND = config(
    "EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend"
)
EMAIL_HOST = config("EMAIL_HOST", default="smtp4dev")
EMAIL_PORT = int(config("EMAIL_PORT", default=25))
EMAIL_HOST_USER = config("EMAIL_HOST_USER", default="")
EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD", default="")
EMAIL_USE_SSL = config("EMAIL_USE_SSL", cast=bool, default=False)
EMAIL_USE_TLS = config("EMAIL_USE_TLS", cast=bool, default=False)
DEFAULT_FROM_EMAIL = config("DEFAULT_FROM_EMAIL", default="info@example.com")

# security configs for production
if config("USE_SSL_CONFIG", cast=bool, default=False):
    # Https settings
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
    SECURE_SSL_REDIRECT = True

    # HSTS settings
    SECURE_HSTS_SECONDS = 31536000  # 1 year
    SECURE_HSTS_PRELOAD = True
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True

    # more security settings
    SECURE_CONTENT_TYPE_NOSNIFF = True
    #  SECURE_BROWSER_XSS_FILTER = True
    X_FRAME_OPTIONS = "SAMEORIGIN"
    SECURE_REFERRER_POLICY = "strict-origin"
    USE_X_FORWARDED_HOST = True
    SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")



#celery configs
CELERY_BROKER_URL = config("CELERY_BROKER_URL", default= 'redis://redis:6379/1')
CELERY_TIMEZONE = config("TIME_ZONE", default= "UTC")
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60

# caching configs
REDIS_CACHE_URL = config("REDIS_CACHE_URL", default= 'redis://redis:6379/2')
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": REDIS_CACHE_URL,
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        },
    }
}

# celery schedule tasks
CELERY_BEAT_SCHEDULE = {
    #Scheduler Name
    'get something': {
        # Task Name (Name Specified in Decorator)
        'task': 'do_periodic_task',  
        # Schedule      
        'schedule': 60,
    },
}

برای ساخت Dockerfile برای پیاده سازی پروژه جنگو می توانید به شکل زیر عمل نمایید:

  1. در پوشه root پروژه خود یک پوشه برای نگهداری فایل های Docker خود با نام Dockerfiles بسازید و برای جدا سازی فاز های پروژه از dev و stage یک پوشه با عنوان prod بسازید و در داخل آن پوشه ای دیگر با نام django ایجاد و در نهایت فایل Dockerfile را ایجاد کنید. ( این عمل صرفا برای تمیز نگه داشتن layout پروژه است)
  2. سپس کافیست محتویات فایل زیر را به داخل آن انتقال دهید
# dockerfiles/prod/django/Dockerfile

# pull official base image
FROM python:3.10-slim-buster

# maintainers info
LABEL maintainer="bigdeli.ali3@gmail.com"

# set work directory
WORKDIR /usr/src/app

# install dependencies
COPY ./requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy project
COPY ./core .

# collecting static files
RUN python3 manage.py collectstatic --no-input

در تنظیمات بالا از image پایتون نسخه 10 و به خصوص slim-buster برای راحتی پیاده سازی و پشتیبانی بیشتر استفاده شده. سپس آدرس نهایی پروژه را با WORKDIR مشخص کرده ایم. ابتدای مراتب فایل requirements را به داخل image منتقل می کنیم و سپس اقدام به آپدیت و نصب ماژول های مربوطه می کنیم. سپس تمام محتوایت پوشه پروژه که core نامیدیم را به داخل image منتثل می کنیم و در آخر تمام فایل های استاتیک را جمع آوری و در داخل پوشه STATIC_ROOT که در settings تعریف کردید می کنیم.

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

آماده سازی دیتابیس در همروش

برای ساخت دیتابیس در پلتفرم همروش کافیست که مراحل زیر را دنبال نمایید، تا بتوانید یک دیتابیس Postgres با نسخه انتخابی خود را ایجاد نمایید. به یاد داشته باشید که پیاده سازی دیتابیس های شخصی سازی شده نیاز به زمان بیشتر و تنظیمات و هزینه بیشتری خواهند داشت و در پلتفرم همروش این مسائل در نظر گرفته شده و در بهینه ترین حالت ممکن ایجاد دیتابیس صورت خواهد گرفت.

  1. ابتدا وارد پلتفرم همروش و بخش darkube شوید.
  2. سپس در بخش دیتابیس ها بر روی PostgreSQL کلیک نمایید
  3. سپس نام اپ مورد نظر و ایمیج مرتبت را انتخاب نمایید و بر روی انتخاب پلن کلیک کنید
  4. حال می توانید مشخصات ذخیار مصرفی سخت افزار را مشخص نمایید و در نهایت بر روی ساخت اپ کلیک نمایید
  5. در نهایت منتظر بالا آمدن سرویس و وضعیت اجرا باشید.
  6. در صفحه اصلی اپ می توانید مشخصات اتصال به دیتابیس را اعم از آدرس داخلی، نام کاربری و رمز عبور را مشاهده نمایید. ( این اطلاعات را در زمان تنظیم پروژه جنگو نیاز خواهیم داشت)

اماده سازی redis در هم رورش

برای ساخت redis سرور در هم روش کافی هستش که در بین دیتابیس ها، دیتابیس redis را انتخاب کرده و سپس اسم اپ و نسخه مورد نظر را انتخاب نمایید و سپس منابع مورد نیاز و در نهای ساخت اپ را کلیک نمایید.

پیاده سازی پروژه جنگو

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

  1. پیاده سازی با منبع git
  2. آپلود فایل

نکته: اهداف این پست برای پیاده سازی از طریق داکر ایمیج و داکر کامپوز نخواهد بود و در پست دیگری بررسی خواهیم کرد.

برای درک بهتر و همچنین یادگیری بهتر تعامل در پست های بعدی از طریق git این کار را خواهیم کرد. پس بر روی منبع git کلیک نمایید. سپس از شما می خواهد که آدرس repo مربوطه را انتخاب کنید.(اگر اولین بار است که از این سرویس استفاده می کنید لازم است که دسترسی های لازم را به repo های خود برای این پلتفرم ایجاد نمایید) انخاب شما می تواند github و یا hamgit(gitlab) سرویس داخلی خود همروش باشد. در این بخش ما github را انتخاب می کنیم و از قبل پروژه خود را به این سرویس منتقل کرده ایم. پس فرم را با مشخصات زیر می توایند پر کنید:

  • آدرس رپو: انتخاب رپوی پروژه
  • نام برنچ: بهتر است برنچ خاصی را برای پیاده سازی اختصاص دهید مثل prod
  • آدرس داکر فایل: dockerfiles/prod/django/Dockerfile
  • build context: که چون قرار است ساخت dockerfile از آدرس روت صورت گیرد آن را " . " قرار می دهیم.
  • دیپلوی خودکار کاملا انتخابی است اگر می خواهید که بدون در نظر گرفتن CI پروژه پیاده سازی شود می توانید در حالت روشن قرار دهید. (در پست های آینده نحوه پیاده سازی CICD را برای شما شرح خواهم داد)
اطلاعات عمومی

در صفحه بعدی نیاز است تا شما در بخش اطلاعات عمومی مشخصات اولیه اپ خود را بنویسید:

  • نام اپ: my-site یا هر اسمی که دوست دارید
  • پورت سرویس: 8000 پورتی است که gunicorn قرار است درخواست ها را گوش و انتقال دهد.
  • دستور اجرایی: در این بخش می بایست دستوری که برای اجرا سرویس شما لازم است وارد شود. که برای اجرای پروژه جنگو ما از طریق gunicorn دستور زیر را قرار می کنیم:
gunicorn --bind 0.0.0.0:8000 core.wsgi:application
Environment Variables

و حال به بخش Environment Variables می رویم:

در این بخش می بایست تمام environment variable های مورد نیاز پروژه را تعریف نماییم که نمونه ای از آن را در زیر می بینید:

SECRET_KEY=asd
DEBUG=False
ALLOWED_HOSTS=*
SITE_ID=1
TIME_ZONE=Asia/Tehran

USE_SSL_CONFIG=True

ENABLE_WHITENOISE=True

PGDB_ENGINE=django.db.backends.postgresql
PGDB_NAME=postgres
PGDB_USER=postgres
PGDB_PASS=tTu8JBMYjz6djadUSro0E6SqPjFcVvZA
PGDB_HOST=my-site.bigdeliali3.svc
PGDB_PORT=5432
DATABASE=postgres


EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=mail.example.com
EMAIL_PORT=465
EMAIL_HOST_USER=no-reply@example.com
EMAIL_HOST_PASSWORD=password
EMAIL_USE_SSL=True
EMAIL_USE_TLS=False
DEFAULT_FROM_EMAIL=no-reply@example.com
آدرس دامنه

و در آخر برای نمایش سایت به بخش آدرس دامنه بروید:

در این بخش آدرس زیر دامنه را برای پروژه خود تعریف می کنیم تا قابلیت نمایش و دسنرسی داشته باشید. در این بخش من صرفا آدرس را my-site می نامم که به شکل https://my-site.drakube.app خواهد بود.

و در انتهای کار بر روی انتخاب پلن کلیک کرده و پلن انتخابی برای اجرا پروژه را مشخص و در نهای ساخت اپ را کلیک می کنیم.

 

نکات پایانی

نکته 1: انتخاب پلن های بیش از حد ضعیف باعث بروز خطا در سرویس خواهند شد

نکته2: در اولین مرحله ایجاد پیاده سازی پاد شکست خواهد خورد زیر را هنوز image مربوطه ایجاد نشده است.

نکته3: پس از ایجاد و آماده شدن و در حالت running قرار گرفتن سایت شما می توانید از آدرس تعریف شده برای دسترسی به آن استفاده نمایید.

نکته4 : برای ساخت اپ worker و beat اپ های مشابهی را ایجاد و ذخایر کمتری را تخصیص می دهید و همچنین نیازی به دادن دامنه به اپ نیست.


اشتراک گذاری:
avatar
علی بیگدلی

نویسنده

دوره های من در مکتبخونه

آموزش جنگو پیشرفته
  • سطح: پیشرفته 4.9
آموزش جنگو Django
  • سطح: مقدماتی 4.6

آخرین پست ها

نحوه نصب و پیاده سازی Caprover بر روی لینوکس
نحوه نصب و پیاده سازی Caprover بر روی لینوکس
  • django 1402/11/29
استفاده از محیط docker-compose و dev container در مدیریت پروژه
استفاده از محیط docker-compose و dev container در مدیریت پروژه
  • django 1402/11/22
پایشگر آب و هوا و کنترل از طریق MQTT با نرم افزار IOT Dashboard
پایشگر آب و هوا و کنترل از طریق MQTT با نرم افزار IOT Dashboard
  • micro python 1402/06/11

آخرین دوره ها

آموزش arduino
آموزش Arduino
  • رایگان 75 دانشجو
آموزش رابط گرافیکی Tkinter
آموزش Tkinter
  • رایگان 390 دانشجو