Создание сайта на Django: урок 55, докеризация проекта Django
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

В корне нашего проекта я создам папку docker, а также файл docker-compose.yml и Dockerfile.

Сам файл Dockerfile будет содержать одно из главных: Python 3.10 и необходимые модули как для самой операционной системы в контейнеры, также и модули необходимые для виртуального окружения нашего Django проекта.

Создадим файл requirements.txt с помощью команды

pip freeze > requirements.txt

Пояснение:

  • Этот файл необходим для установки всех модулей виртуального окружения, в том числе и самого Django.
  • Также в получившийся файл нужно добавить gunicorn. Его можно прописать вручную:

requirements.txt

gunicorn
amqp==5.1.1
asgiref==3.5.2
async-timeout==4.0.2
billiard==3.6.4.0
celery==5.2.7
click==8.1.3
click-didyoumean==0.3.0
click-plugins==1.1.1
click-repl==0.2.0
colorama==0.4.5
Deprecated==1.2.13
Django==4.1
django-ckeditor-5==0.2.0
django-cleanup==6.0.0
django-debug-toolbar==3.6.0
django-js-asset==2.0.0
django-mptt==0.13.4
django-recaptcha==3.0.0
django-taggit==3.0.0
kombu==5.2.4
packaging==21.3
Pillow==9.2.0
prompt-toolkit==3.0.31
psycopg2==2.9.3
pyparsing==3.0.9
pytils==0.4.1
pytz==2022.2.1
redis==4.3.4
six==1.16.0
sqlparse==0.4.2
tzdata==2022.2
vine==5.0.0
wcwidth==0.2.5
wrapt==1.14.1

Также в settings.py нужно добавить следующее:

backend/settings.py

ALLOWED_HOSTS = ['127.0.0.1']

CSRF_TRUSTED_ORIGINS = ['http://127.0.0.1']

Пояснение:

  • Необходимо добавить для того, чтобы сервер Django работал на деплое. 
  • Где 127.0.0.1 - ваш будущий домен.

Dockerfile

FROM python:3.10.6-buster

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

# Обновление системы
RUN apt-get update
RUN apt-get -y install postgresql-client gcc

# Обновление pip python
RUN pip install --upgrade pip

# Установка требований

COPY requirements.txt ./requirements.txt

RUN pip install -r requirements.txt

# Рабочий каталог

WORKDIR /app

# Копирование проекта

COPY . .

docker-compose.yml

version: '3.8'

volumes:
  pgdata:
  static:
  media:

services:
  # Веб-приложение Django (env добавить)
  django:
    build:
      context: .
    ports:
      - '8000:8000'
    container_name: django
    env_file:
      - docker/env/.env.prod
    volumes:
      - ./:/app
      - static:/app/static
      - media:/app/media
    depends_on:
      - postgres
      - redis
    command: sh -c "python manage.py collectstatic --no-input &&
                    python manage.py makemigrations &&
                    python manage.py migrate &&
                    gunicorn --workers=4 --reload --max-requests=1000 backend.wsgi -b 0.0.0.0:8000"
  # Веб-сервер NGINX
  nginx:
    build: docker/nginx/
    container_name: nginx
    restart: always
    volumes:
      - ./docker/nginx/:/etc/nginx/conf.d
      - ./docker/letsencrypt:/etc/letsencrypt
      - static:/app/static
      - media:/app/media
    ports:
      - '80:80'
      - '443:443'
    links:
      - django
    depends_on:
      - django
  # База данных PostgreSQL
  postgres:
    image: postgres:buster
    container_name: postgres
    restart: always
    env_file:
      - docker/env/.env.prod
    volumes:
      - pgdata:/var/lib/postgresql/data/
  # База кэширования Redis
  redis:
    image: redis:buster
    container_name: redis
    env_file:
      - docker/env/.env.prod
    expose:
      - 6379
    volumes:
      - ./docker/redis/data:/data
      - /.docker/redis/etc/redis.conf:/usr/local/etc/redis/redis.conf
  # Асинхронный обработчик
  celery-worker:
    build: .
    container_name: celery-worker
    restart: always
    env_file:
      - docker/env/.env.prod
    volumes:
      - ./:/app
      - media:/app/media
    command: celery -A backend worker -B --loglevel=info --logfile=docker/logs/celery-worker.log
    depends_on:
      - redis

Пояснение:

  • В сервисах мы создаем Django, Nginx, Postgres, Redis и Celery контейнеры.
  • Задаем определенные названия через container_name
  • Я в работу проекта подключу env_file с глобальными переменными для виртуального окружения.
  • .env.prod будет находиться у нас в папке docker/env. Надеюсь вы знаете как работают env файлы, для чего они нужны, и как настраивать данные в settings.py для работы с env
  • Логи celery тоже будут храниться в папке docker/logs/
  • А такие данные, как например конфиг и сохраненный кэш будет храниться тоже в папке docker/redis.

Nginx у нас создается из файла Dockerfile, который мы создадим в папке docker/nginx.

docker/nginx/Dockerfile

FROM nginx:latest

RUN rm /etc/nginx/conf.d/default.conf

COPY nginx.conf /etc/nginx/conf.d

Пояснение:

  • Устанавливаем последнюю версию nginx, удаляем дефолтный конфиг и копируем свой конфиг. Этот конфиг покажу ниже:

docker/nginx/nginx.conf

upstream django {
    server django:8000;
}

server {
    listen 80;
    # Settings
    client_max_body_size 100M;
    charset utf-8;
    # Gzip
    gzip  on;
    gzip_disable "msie6";
    gzip_min_length 1000;
    gzip_vary on;
    gzip_proxied   expired no-cache no-store private auth;
    gzip_types     text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    location / {
        proxy_pass http://django;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /static/ {
        alias  /app/static/;
        expires 15d;
     }

     location /media/ {
        alias  /app/media/;
        expires 7d;
    }
}

Также в папке Docker создам папку logs, redis, env.

В папке env я создам файл .env.prod со своими необходимыми переменными.

DJANGO_SECRET_KEY=
DJANGO_DEBUG=0
CSRF_TRUSTED_ORIGINS=
ALLOWED_HOSTS=
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_DB=
POSTGRES_HOST=
POSTGRES_PORT=
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/0
REDIS_LOCATION=redis://redis:6379/1
RECAPTCHA_PUBLIC_KEY=
RECAPTCHA_PRIVATE_KEY=
EMAIL_HOST=
EMAIL_PORT=
EMAIL_USE_TLS=
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=

После = свои значения.

В settings.py подключать следующим образом, пример покажу из небольшого фрагмента кода:

backend/settings.py

import os

SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')

DEBUG = int(os.environ.get('DJANGO_DEBUG', default=0))

ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS').split()

CSRF_TRUSTED_ORIGINS = os.environ.get('CSRF_TRUSTED_ORIGINS').split()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('POSTGRES_DB'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST'),
        'PORT': os.environ.get('POSTGRES_PORT'),
    }
}

Думаю вам будет ясно, как добавлять значения и для других настроек. 

Структура должна получиться такой же:

А в следующем уроке мы попробуем запустить контейнер и может быть рассмотрим деплоинг на сервер. 

Также, советую ознакомиться с этими уроками, если вы не установили Docker на Ubuntu 22.04

Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)