Как использовать Django, PostgreSQL и Docker

Docker — утилита для упаковки, загрузки и запуска любых приложений в легковесных контейнерах.

Контекст сборки образа Docker

Для сборки нового образа Docker используется команда docker build. У команды build есть аргумент, который задает контекст сборки (build context) .

Что такое контекст сборки для Docker?

Напомним, что Docker является клиент-серверным приложением, которое состоит из Docker-клиента и Docker-сервера (Docker-демона). Инструмент командной строки Docker-клиента командами сообщает Docker-серверу, что нужно делать. Одной из команд является build – создание нового образа Docker. Docker-сервер может работать на той же машине, что и клиент, либо на удаленной машине.

Почему это важно и как это связано с контекстом сборки Docker?

Чтобы создать новый образ, Docker-серверу нужен доступ к файлам, из которых будет создаваться образ. Поэтому необходимо каким-то образом передать эти файлы на Docker-сервер. Эти файлы являются контекстом сборки Docker. Docker-клиент упаковывает все файлы контекста сборки в архив tar и загружает этот архив на Docker-сервер. По умолчанию, клиент использует текущий каталог в качестве контекста сборки.

В качестве контекста сборки также можно использовать заранее подготовленный архив tar или репозиторий git. При использовании git клиент клонирует репозиторий с подмодулями во временный каталог и создает из него архив контекста сборки.

Команды Dockerfile

Dockerfile – это скрипт, который содержит в себе инструкции, которые будут использоваться для создания образа Docker с помощью команды «docker build». Для создания Dockerfile нужно знать некоторый его команды.

Инструкция FROM инициализирует новый этап сборки и должна располагаться в верхней части Dockerfile.

LABEL

С помощью этой инструкции вы можете добавить дополнительную информацию о вашем образе Docker, такую ​​как версия, описание и т.д.

Читайте также:  Настройка Nginx в качестве reverse прокси для Apache

Эта инструкция используется для выполнения команды в процессе сборки образа Docker. Вы можете установить дополнительные пакеты, необходимые для ваших образов Docker.

Инструкция ADD используется для копирования файлов, каталогов или файлов из удаленных русурсов в ваши образы Docker. Кроме того, вы можете настроить права на файл по умолчанию.

Инструкция ENV используется для определения переменной среды, которая может использоваться на этапе сборки.

CMD используется для определения команды по умолчанию для выполнения при запуске контейнера. Dockerfile должен содержать только одну инструкцию CMD, и, если имеется несколько CMD, будет выполняться последняя инструкция CMD.

EXPOSE

Эта инструкция используется для предоставления порта контейнера на определенных сетевых портах во время выполнения. По умолчанию используется протокол TCP, но вы можете указать, будет ли он TCP или UDP.

Инструкция ARG используется для определения переменной, которую пользователь может передать сборщику образа. Вы можете использовать эту инструкцию в docker ‘build command’ во время сборки, используя опцию ‘–build-arg variable = value’. Также вы можете использовать несколько ARG в Dockerfile.

ENTRYPOINT

Инструкция ENTRYPOINT используется для определения первой команды и команды по умолчанию, которая будет выполняться при запуске контейнера. Определите команду для запуска приложения с помощью инструкции ENTRYPOINT.

WORKDIR

Инструкция WORKDIR используется для определения рабочего каталога по умолчанию вашего образа Docker. Инструкции RUN, CMD, ENTRYPOINT и ADD следуют за инструкцией WORKDIR. Вы можете добавить несколько инструкций WORKDIR в ваш Dockerfile. Если она не существует, она будет создана автоматически.

Инструкция USER используется для определения пользователя или gid по умолчанию при запуске образа. RUN, CMD и ENTRYPOINT следуют за инструкциям USER в Dockerfile.

VOLUME

Инструкция VOLUME используется для создания точки монтирования между контейнером и базовым хостом.

Ограничим память

Первое, что может прийти на ум — это ограничить размер самого Docker-контейнера. Создадим простое приложение на Spring Boot и запустим контейнер, поставив ограничение памяти 150 мегабайт. Вот пример команды на хосте с одним гигабайтом памяти:

$ docker run -it —rm —name mycontainer150 -p 8080:8080 -m 150M rafabene/java-container:openjdk

Читайте также:  Установка Awesome Zsh и создание ее оболочкой по умолчанию

В приложении заранее был создан rest-метод, который загружает память до отказа объектами типа String. Вызовем его:

$ curl http://`docker-machine ip docker1024`:8080/api/memory

Вызванный метод возвращает что-то вроде «Выделено более чем 80% памяти (219.8 MiB) из максимально доступных JVM (241.7 MiB) «.

Но отсюда два вопроса:

1. Почему максимальный размер для JVM 241 мегабайт?

2. Если мы выше указали, что контейнеру доступно только 150 мегабайт памяти, то почему приложение потребляет почти 220?

Первое, что нужно помнить о максимальном размере кучи (max heap size) у JVM, это то, что размер по умолчанию будет занимать 1/4 памяти. И второе — когда мы при запуске контейнера выше указывали флаг «-m 150M», то докер зарезервировал 150 мегабайт в оперативной памяти и 150 мегабайт в Swap. Поэтому-то приложение и не рухнуло и отработало как нужно. Но при этом вы должны понимать, что увеличение памяти в контейнере — это не решение проблемы. Всегда может случиться ситуация, когда Java-приложение может выйти за рамки лимита, и тогда процесс будет убит.

Инициируем Swarm-режим

Получим команды, которые настроят текущий shell для работы с демоном Docker на виртуальной машине:

docker-machine env vm0

Будет выведен список команд для текущей оболочки, которые нужно выполнить. В списке машин (docker-machine ls) в колонке ACTIVE символом * будет отмечена активная машина. Теперь все команды docker … будут выполняться на ней.

Для инициации swarm-режима выполняем:

docker swarm init

В ответе будет указано, что текущая машина теперь менеджер. Также будет выведена команда для подключения к swarm рабочих нод.

Погнали!

Внимание Хост для доступа к MySQL — mysql. Не localhost, а именно mysql.

Минимальная конфигурация для нашей локальной разработки готовы. Осталось только запустить ее и проверить, работает ли оно. Переходит в корень нашего проекта, где лежит файл Выполняем команду docker-compose up -d и ждем. Первый запуск он самый долгий, потому что докеру нужно скачать образы и собрать наш образ php.

Читайте также:  SEO инструменты: Управление мета тэгами PRO

В самом конце мы увидим заветные строки:

1 2 3 4 5 6 7 8

Starting source_mysql_1 … Starting source_mysql_1 … done Starting source_php_1 … Starting source_php_1 … done Starting source_nginx_1 … Starting source_nginx_1 … done Starting source_pma_1 … Starting source_pma_1 … done

Они сообщают нам, что все 4 контейнера поднялись и работают. Проверим все ли так. Открываем браузер и переходим по адресу :8000/ и нихрена не открывается. Все потому, что нам надо в файл host прописать следующею строку:

Погнали!

1

127.0.0.1

Обновляем страницу и видим:

Все готово, все работает. Для создания дополнительного хоста нам нужно в папке www создать папку проекта, а в папке hosts создать для него конфиг nginx и перезапустить контейнеры. Удачи!

Инфо Т.к. сейчас хром да и все остальные по умолчанию пытаются стучать в https рекмендую для локальной разработки создавать домены вида Хром успокаивается и пускает вас поработать.

Заключение

В этой статье мы рассмотрели, как создать контейнер для веб-приложения Django с Postgres. Мы также создали готовый к работе файл Docker Compose, который добавляет Gunicorn и Nginx в нашу конфигурацию для обработки статических и мультимедийных файлов. Теперь вы можете проверить производственную настройку локально.

С точки зрения фактического развертывания в производственной среде, вы, вероятно, захотите использовать:

  1. Полностью управляемый сервис базы данных— такой как RDS или Cloud SQL — вместо того, чтобы управлять своим собственным экземпляром Postgres в контейнере.
  2. Пользователь без полномочий root для db и nginx сервисов

Для других советов работы с производственной средой, см эту дисскусию.

Спасибо за чтение

Источники используемые для этой статьи

  • William Vincent — How to use Django, PostgreSQL, and Docker
  • Michael Herman — Dockerizing Django with Postgres, Gunicorn, and Nginx

Была ли вам полезна эта статья? [19 / 4.7]Spread the love