Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

11.7 Подготовка к деплою, Gunicorn и NGINX в Docker Compose
3 из 3 шагов пройдено

Теперь создадим образ докера для создания контейнера с Django.

В данном примере будет использоваться мульти-образ для экономии места. builder - это временный образ с помощью которого будут созданы бинарные файлы библиотек Python. После создания образа builder с него будут скопированы файлы в наш основной образ.

Создадим файл app/Dockerfile.prod:

###########
# BUILDER #
###########

FROM python:3.12.0-alpine as builder

WORKDIR /usr/src/app

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# установка зависимостей
RUN apk update \
    && apk add postgresql-dev gcc python3-dev musl-dev
RUN pip install --upgrade pip

# установка зависимостей
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt


#########
# FINAL #
#########

FROM python:3.12.0-alpine

# создаем директорию для пользователя
RUN mkdir -p /home/app

# создаем отдельного пользователя и его группы
RUN addgroup -S app && adduser -S app -G app

# создание директории для проекта Django
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

# установка зависимостей
RUN apk update && apk add libpq
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*

# копирование entrypoint-prod.sh
COPY ./entrypoint.prod.sh $APP_HOME

# копирование проекта Django
COPY . $APP_HOME

# смена владельца файлов и директорий проекта Django, на пользователя app
RUN chown -R app:app $APP_HOME

# изменение рабочего пользователя
USER app

# установим права и запустим скрипт проверки запуска БД
RUN chmod +x /home/app/web/entrypoint.prod.sh
ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]

В образе мы создали пользователя app и его группу app. Это делается для того, что бы не использовать пользователя root, который используется по умолчанию в контейнерах Docker.

Создадим файл entrypoint.prod.sh в папке app, рядом с Dockerfile.prod

#!/bin/sh

if [ "$DATABASE" = "postgres" ]
then
    echo "Postgres еще не запущен..."

    # Проверяем доступность хоста и порта
    while ! nc -z $SQL_HOST $SQL_PORT; do
      sleep 10
    done

    echo "PostgreSQL запущен"
fi

exec "$@"

Данный файл необходим чтобы проверить работоспособность PostgreSQL перед применением миграции и запуском сервера разработки Django.
Изменим файл docker-compose.prod.yml, что бы он использовал новый файл - Dockerfile.prod:

version: '3.8'

services:
  web:
    # Берем Dockerfile из каталога app
    build:
      context: ./app
      dockerfile: Dockerfile.prod
    # Запускаем сервер gunicorn
    command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
    # Открываем порт 8000 внутри и снаружи
    ports:
      - 8000:8000
    # Файл содержащий переменные для контейнера
    env_file:
      - .env.prod
    # Дожидаемся запуска контейнера db и memcached
    depends_on:
      - db
      - memcached
  db:
      image: postgres:15
      volumes:
        - postgres_data:/var/lib/postgresql/data/
      environment:
        - POSTGRES_USER=book_django
        - POSTGRES_PASSWORD=pass_book_django
        - POSTGRES_DB=book_django
  memcached:
      image: memcached:1.6.21
      ports:
        - 11211:11211
volumes:
  postgres_data:


Протестируем:

docker-compose -f docker-compose.prod.yml down -v
docker-compose -f docker-compose.prod.yml up -d --build
docker-compose -f docker-compose.prod.yml exec web python manage.py migrate --noinput

И откроем в браузере http://127.0.0.1:8000, мы видим что все прекрасно работает через Gunicorn.


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Что бы entrypoint.prod.sh выполнялся разве не нужно указать в Dockerfile что то типа? 

ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]

@Николай_Петров, Спасибо, добавил.

После билд мне еще приходится docker-compose up -d web выполнять.

@Ilia_Boiarintsev, А ошибок нет никаких при создании образов?

@Илья_Перминов, не знаю. Как это выяснить?

@Илья_Перминов, вот такая ситуация получается

@Ilia_Boiarintsev, странно, хотя пишет что контейнер веб запущен.

Когда выполняю docker-compose -f docker-compose.prod.yml up -d --build

failed to solve: failed to compute cache key: failed to calculate checksum of ref 427b0104-d112-4b23-8d90-2dc648c6b05e::th80vm8qonoloedozplb4pzvd: "/entrypoint.prod.sh": not found

Изменен Попов Станислав

@Попов_Станислав, изменяли ли Dockerfile.prod ? Пути, или еще что нибудь? Просто докер не может найти entrypoint.prod.sh в рабочей директории контейнера.

@Илья_Перминов, а что такое entrypoint.prod.sh? Мы же его нигде не создавали, не прописывали вроде.
Вот мой Dockerfile.prod:

###########

# BUILDER #

###########

 

FROM python:3.12.0-alpine as builder

 

WORKDIR /usr/src/app

 

ENV PYTHONDONTWRITEBYTECODE 1

ENV PYTHONUNBUFFERED 1

 

# установка зависимостей

RUN apk update \

&& apk add postgresql-dev gcc python3-dev musl-dev

RUN pip install --upgrade pip

 

# установка зависимостей

COPY ./requirements.txt .

RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt


 

#########

# FINAL #

#########

 

FROM python:3.12.0-alpine

 

# создаем директорию для пользователя

RUN mkdir -p /home/app

 

# создаем отдельного пользователя и его группы

RUN addgroup -S app && adduser -S app -G app

 

# создание директории для проекта Django

ENV HOME=/home/app

ENV APP_HOME=/home/app/web

RUN mkdir $APP_HOME

WORKDIR $APP_HOME

 

# установка зависимостей

RUN apk update && apk add libpq

COPY --from=builder /usr/src/app/wheels /wheels

COPY --from=builder /usr/src/app/requirements.txt .

RUN pip install --no-cache /wheels/*

 

# копирование entrypoint-prod.sh

COPY ./entrypoint.prod.sh $APP_HOME

 

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

COPY . $APP_HOME

 

# смена владельца файлов и директорий проекта Django, на пользователя app

RUN chown -R app:app $APP_HOME

 

# изменение рабочего пользователя

USER app

@Попов_Станислав, извиняемся, забыли добавить в лекцию. Сейчас добавили, пробуйте.

@Илья_Перминов,  работает, спасибо