نحوه Dockerize کردن Django و Postgre و Nginx - برای محیط Stage

1402/05/03 | 298 |
django

در این پست به نحوه داکرایز کردن پروژه های جنگو برای فاز stage خواهیم پرداخت و در ادامه به راه کار های موجود و یک قالب آماده برای پیاده سازی پروژه های جنگو را به شما معرفی خواهیم کرد. در نظر داشته باشید که برای درک این موضوع نیاز به یادگیری داکر خواهید داشت و می بایست تا حد خیلی خوبی به ساختار ایجاد Dockerfile و همچنین استفاده از docker-compose اشراف داشته باشید.

 

پیاده سازی پروژه های جنگو با قالب آماده من

 
لینک رپو: 

 

در قسمت قبل دیدید که چطور می توان با داکرایز کردن جنگو در محیط توسعه کار را برای توسعه نرم افزار های جنگو ساده تر و سریعتر کرد، اما در این قسمت می خواهیم تا به یک پیاده سازی اولیه برای روی VPS و یا ماشین های مجازی بپردازیم، به طوری که سرویس جنگو قرار است با استفاده از ارتباطی که با Gunicorn و Nginx بر قرار می کند درخواست های کاربران را پاسخگو باشد. برای این کار لازم است طبق دستور العمل زیر پیش برویم.

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

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

در ساختار بالا دو نکته است:

  1. جنگو برای سرو کردن فایل های media و static دیگر به صورت مستقیم در حالت DEBUG=False قادر نخواهد بود، و سرو آن ها توسط nginx انجام خواهد شد.
  2. جنگو برای اینکه بتواند درخواست کاربران را دریافت کند نیاز به تنظیمات nginx در بخش config خواهد داشت که به زودی خواهید دید.

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

│   .gitattributes
│   LICENSE
│   README.md
│   .gitignore
│   requirements.txt
└─── core
      ├─── staticfiles
      ├─── static
      ├─── media
      ├─── manage.py
      └─── core
            │   asgi.py
            │   error_views.py
            │   settings.py
            │   urls.py
            │   wsgi.py
            └─── __init__.py
    

با توجه به ساختار بالا در نظر داشته باشید که تنظیمات سرو کردن فایل های Static و media را می بایست در ابتدا انجام دهیم. که به شکل زیر خواهد بود:

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

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


STATICFILES_DIRS = [
    BASE_DIR / "static",
]

 

ساخت requirements

پس از ایجاد تنظیمات بالا نیاز است که برای پروژه جنگو خود فایل requirements.txt را ایجاد و تمام ماژول هایی که قرار است استفاده کنیم را درج نماییم. که نمونه زیر حاوی ماژول gunicorn است.

# requirements.txt

# general  modules
django >3.2,<3.3

# env controls
python-decouple

# deployment module
gunicorn

# database client
psycopg2-binary

 

ساخت Dockerfile

بخش تنظیمات نرم افزار به پایان رسیده و حال می بایست به ساخت Dockerfile و docker-compose بپردازیم. در ساخت Dockerfile کافیست که به شکل زیر عمل نمایید. و تنظیمات لازم را برای Dockerfile مربوط به جنگو در نظر بگیرید.

# dockefiles/stage/django/Dockerfile

# pull official base image
FROM python:3.10-alpine as base

LABEL maintainer="bigdeli.ali3@gmail.com"

RUN apk add --update --virtual .build-deps \
    build-base \
    postgresql-dev \
    python3-dev \
    libpq


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


# Now multistage build
FROM python:3.10-alpine
RUN apk add libpq
COPY --from=base /usr/local/lib/python3.9/site-packages/ /usr/local/lib/python3.9/site-packages/
COPY --from=base /usr/local/bin/ /usr/local/bin/

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy project
COPY ./core .

در فایل بالا برای پایین نگه داشتن حجم و سطح دسترسی کاربری python با استفاده از alpine-image اقدام به ساخت کانتینر می کنیم که در دو مرحله صورت میگیرد. مرحله اول نصب ماژول ها و آماده سازی پکیج ها خواهد بود ( در صورتی که بخوایهد از این dockerfile برای ساخت کانتینر های worker ویا beater استفاده نمایید حجم کمتری اشغال می شود) و در مرحله بعدی سورس اصلی که قرار است پیاده سازی بر روی آن صورت بگیرد ساخته خواهد شد.

سپس برای nginx نیاز است که dockerfile دیگری ایجاد شود تا بتوان تنظیماتی که در زیر ایجاد می کنید را به آن منتقل و در زمان اجرا در دسترس سرویس قرار داد.

# dockerfiles/stage/nginx/Dockerfile

FROM nginx:alpine
COPY ./conf.d/ /etc/nginx/conf.d/

در پوشه ای که فایل Dockefile مروبط به nginx قرار دارد یک دایرکتوری با نام conf.d ایجاد نمایید و سپس فایل زیر را در آن ایجاد کنید. این فایل حاوی تنظیمات ومفاهیم تغییر و انتقل درخواست کاربر به سمت سرویس django خواهد بود:

# dockerfiles/stage/nginx/conf.d/default.conf


server {
    listen 80;
    server_name _;
     
     # server logs
    access_log  /var/log/nginx/example.log;
    error_log /var/log/nginx/mysite.error.log;

    server_tokens off;
    client_max_body_size 10M;


    # static files directory
    location /static/ {
      autoindex on;
      alias /home/app/static/;
    }
    
    # media files directory
    location /media/ {
      autoindex on;
      alias /home/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://backend:8000;
    }
}

در فایل بالا برای سرو کردن static و media ها دو آدرس مطابق با آدرس هایی که در url جنگو تعریف کرده اید را قرار می دهید. سپس آدرس root را به سرویس جنگو منتقل کرده و از پورت 80 سرویس nginx به پورت 8000 gunicorn منتثل خواهیم کرد.

ساخت docker-compose

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

# docker-compose-stage.yml

version: "3.9"

services:

  db:
    container_name: db
    image: postgres:alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    env_file:
      - envs/stage/db/.env
    restart: always
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U postgres']
      interval: 10s
      timeout: 5s
      retries: 5

  backend:
    build:
      context: .
      dockerfile: dockerfiles/stage/django/Dockerfile
    container_name: backend
    command: sh -c "python3 manage.py check_database && \
                    python3 manage.py makemigrations --noinput && \
                    python3 manage.py migrate --noinput && \
                    python3 manage.py collectstatic --noinput && \
                    gunicorn --bind 0.0.0.0:8000 core.wsgi:application"
    volumes:
      - ./core:/usr/src/app
      - static_volume:/usr/src/app/static
      - media_volume:/usr/src/app/media
    expose:
      - "8000"
    env_file:
      - envs/stage/django/.env
    depends_on:
      - db

  nginx:
    build:
      context: ./dockerfiles/stage/nginx/
    container_name: nginx
    restart: always
    ports:
      - "80:80"
    volumes:
      - static_volume:/home/app/static
      - media_volume:/home/app/media
    depends_on:
      - backend


volumes:
  static_volume:
  media_volume:
  postgres_data:

در فایل بالا سرویس backend را مشاهده می کنید که دو آدرس volume برای سرو کردن فایل های static و media و درج در فضای کانتینر را دارد. و این volume ها به صورت کلی توسط هر سرویس دیگر قابل دسترس خواهند بود و به عنوان مثال سرویس nginx با توجه به تنظیمات فعلی اطلاعات حاوی این volume ها را به آدرسی در سرویس خود متصل و link می کند و بدین صورت می تواند به دیتا های سرویس جنگو دسترسی داشته باشد. دستوری که برای اجرا سرویس django مشاهده می کنید جهت راه اندازی gunicorn است که بتواند با سرویس جنگو ما ارتباط بر قرار کند و همچنین درخوسات کاربران را به این سرویس منتقل نماید.

 در اینجا برای اینکه بتوانید پروژه خود را اجرا کنید لازم است تا دستور docker-compose برای build و به اجرا در آوردن سرویس ها را در محل قرار گیری فایل docker-compose.yml اجرا کنید که به شکل زیر خواهد بود.

docker-compose -f docker-compose-stage.yml up --build

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

docker-compose -f docker-compose-stage.yml stop # برای توقف 

docker-compose -f docker-compose-stage.yml down # برای از بین بردن سرویس ها

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


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
  • رایگان 78 دانشجو
آموزش رابط گرافیکی Tkinter
آموزش Tkinter
  • رایگان 402 دانشجو