پیاده سازی Django با Nginx در همروش - به همراه disk و media

1402/05/14 | 392 |
django

در این آموزش به بررسی نحوه پیاده سازی پروژه های جنگو در پلتفرم همروش خواهیم پرداخت.در این آموزش علاوه بر پیاده سازی جنگو سرو کردن فایل های استایک و media را هم با استفاده از دیسک در این پلتفرم نمایش خواهیم داد.

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

 

 

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

AliBigdeli/Django-Hamravesh-Nginx-Gunicorn-SameContainer-App: a simple example of deploying django and gunicorn and nginx in the same contianer docker (github.com)

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

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

  1.  آماده سازی پروژه در محیط Local
  2. آماده سازی دیتابیس در هم روش
  3. پیاده سازی پروژه django

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

قبل از آنکه بخواهید پروژه خود را وارد پلتفرم همروش نمایید می بایست بعضی ساختار ها را در پروژه خود اعمال کنید که تا بتوان از طریق این سرویس پروژه شما قابلیت اجرا داشته باشد. از جمله اماده سازی ها می توان به داشتن 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

# your other modules goes here

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

....

STATIC_URL = "/static/"
MEDIA_URL = "/media/"

STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_ROOT = BASE_DIR / "media"


STATICFILES_DIRS = [
    BASE_DIR / "static",
]
....



....

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

....


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

به یاد داشته باشید که تمام بخش های دیگر پروژه که نیاز است که از بیرون اعمال شوند را به حالت 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")

برای ساخت 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 up Gunicorn
COPY ./core .

# Install Nginx
RUN apt-get update && apt-get install -y nginx


# Configure Nginx
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf

# exposing nginx port
EXPOSE 80


# copy entrypoint
COPY ./dockerfiles/prod/django/entrypoint.sh .

# make our entrypoint.sh executable
RUN chmod +x ./entrypoint.sh

# execute our entrypoint.sh file
CMD ["./entrypoint.sh"]

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

# dockerfiles/prod/django/entrypoint.sh

#!/bin/bash

python manage.py collectstatic --no-input

gunicorn core.wsgi:application --bind "0.0.0.0:8000" --daemon

nginx -g 'daemon off;'

در entry point بالا ابتدا static ها جمع آوری شده و سپس gunicorn رادر حالت Daemon اجرا کرده تا در پس زمینه انجام شود و سپس nginx را در حالت main thread اجرا می کنیم و daemon آن را غیر فعال می کنیم تا همیشه در حالت اجرا باقی بماند.

فایلی که تنظیمات nginx از آن استفاده خواهند کرد به شکل زیر خواهد بود که فایل های media را از طریق آدرس دهی داخلی سرو خواهد کرد  و درخواست های دیگر به آدرس سرویس django منتثل خواهند شد:

# nginx/nginx.conf

events {
  
}

http {
  server {
      listen 80;

      server_tokens off;
      client_max_body_size 10M;

      
      # media files directory
      location /media/ {
        autoindex on;
        alias /usr/src/app/media/;
      }

      location / {        
          proxy_redirect     off;
          proxy_set_header   Host $host;
          proxy_set_header   REMOTE_ADDR $remote_addr;
          proxy_set_header   X-Url-Scheme $scheme;
          proxy_set_header   X-Real-IP $remote_addr;
          proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass   http://127.0.0.1:8000;
      }
  }
}

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

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

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

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

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

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

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

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

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

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

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

  • نام اپ: my-site یا هر اسمی که دوست دارید
  • پورت سرویس: 80 پورتی است که nginx داخلی ما بر روی آن اجرا می شود.
  • دستور اجرایی: در این بخش دستور اجرایی ما خالی خواهد بود چرا که nginx در Entrypoint در حالت اجرا قرار میگیرد
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 خواهد بود.

ایجاد disk

در این مرحله نیاز است که به اندازه نیاز خود یک دیسک به پروژه اضافه کنین برای شروع می تواند این مقدار برابر  1 گیگ باشد و در مرحله بعد لازم است که این محل قرار گیری آن را به شکل زیر تعریف کنید: 

  • نام : media
  • آدرس: usr/src/app/media

نکات پایانی

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

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

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


avatar
علی بیگدلی

نویسنده

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

آموزش شی‌ءگرایی در پایتون
  • سطح: متوسط 94% رضایت
آموزش جنگو Django
  • سطح: مقدماتی 97% رضایت
آموزش جنگو پیشرفته
  • سطح: پیشرفته 99% رضایت

آخرین پست ها

نحوه نصب و پیاده سازی 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
  • رایگان 54 دانشجو
آموزش رابط گرافیکی Tkinter
آموزش Tkinter
  • رایگان 286 دانشجو