PostgreSQL в контейнере Docker

Н о, в продолжение той статьи, рекомендую разобраться в основных отличиях образа и контейнера в Docker, а еще (вот это уже по желанию), подробнее почитать про слои и не только в Docker.
Подключение через psql с хостовой машины:
Подключение к контейнеру:
Внутри него подключение к psql:
Приступим к длинной статье со скриншотами и теми ошибками, которые я словил.
Сначала нужно найти образ с нужной версией PostgreSQL, я использую команду:
Буду использовать верхний (официальный) контейнер, 12 версия. Скачиваю его с помощью команды:
Нужно немного подождать, всё-такие размер образа составляет 314 мегабайт, так что зависит от скорости интернета.
Размер образов можно посмотреть командой:
Теперь можно контейнер запускать (в статье по ссылке выше отличие образов от контейнеров есть). Попробую сделать это вот такой командой:
Появляется ошибка (на самом деле, команду выше надо дополнить, тогда всё нормально будет, но на ошибку тоже нужно посмотреть):
Текст ошибки можете сами прочитать. Суть — нужно произвести различные инициализации, указать пароли и так далее, чтобы контейнер правильно сформировался. Я же этого не сделал еще, так что в базу зайти не могу. То есть, нужно правильно команду запуска сформировать.
Наверное, в данном случае лучше зайти на ту страницу, с которой производили скачивание образа postgres — со страницы хранилища контейнеров, dockerhub. В поле поиска вбиваем имя и находим результат:
Попадаем на страницу с описанием данного контейнера:
Описание большое, желательно всё прочитать. Я чутка поторопился, поискал в интернете интересующую меня информацию, мне ведь хотелось запустить контейнерный PostgreSQL и подключиться к нему. Поэтому, про официальную страницу помните и изучите её, а я далее покажу, что делал.
ВАЖНО: Возможно, что-то я делаю не правильно. Но я только начал изучать Docker, так что ошибки могут быть. Но код ниже работает 🙂
Итак, сначала предлагаю проверить, доступен ли «запущенный» выше PostgreSQL. Для этого я попробую запустить psql (можно установить с помощью команды apt и нужного пакета, там за версией надо следить) и подключиться к чему-нибудь:
Появляется ошибка — естественно, ведь PostgreSQL у меня не установлен.
Вот теперь запускаем контейнер с PostgreSQL следующей командой:
Убедимся, что всё получилось:
Снова попробуем подключиться к контейнерному PostgreSQL с помощью psql, установленного на хостовой машине:
Обратите внимание, что нужно ввести тот пароль, который указали в команде run:
Всё получилось! Можно даже таблицу создать:
Теперь осталось подключиться к PostgreSQL из контейнера. Для этого необходимо выполнить вот такую команду:
Можно походить по директориям. Подключены как пользователь ОС root.
Видим все те данные, которые были созданы с хоста. Еще можно найти каталог с данными и зайти туда — и можно там похозяйничать, если нужно.
Напоминаю, что, если удалить контейнер — все пользовательские (созданные нами) данные потеряются!
Например, я сейчас останавливаю мой контейнер, потом его удаляю, создаю заново, подключаюсь и вижу:
Можно свой образ сделать с этими данными, а потом его использовать.
Уф, ну вроде всё! Наверное, я буду контейнер с PostgreSQL использовать для различных тестирований — удобно и быстро, заморачиваться с виртуальной машиной не надо.
Установка и настройка PostgreSQL в Docker
Docker — удобный инструмент для создания изолированных сред. Именно этой своей особенностью он и удобен для разворачивания различных приложений, требующих дополнительных зависимостей.
Managed Kubernetes помогает разворачивать контейнерные приложения в инфраструктуре Selectel. Сосредоточьтесь на разработке, а мы займемся рутинными операциями по обеспечению работы вашего кластера Kubernetes.
В прошлой статье о Docker-контейнерах мы рассказывали о преимуществах контейнеризации в целом, а в этой рассмотрим их относительно СУБД PostgreSQL, также расскажем о ее установке внутри контейнера.
Зачем использовать PostgreSQL в контейнере
Чтобы больше понять о преимуществах контейнеризации PostgreSQL, немного забежим вперед и для примера посмотрим на те зависимые пакеты, которые автоматически будут установлены вместе с приложениями, относящимся непосредственно к PostgreSQL, если мы будем ставить СУБД на сервер:
В нашем примере их три: libllvm10, libpq5, libxslt1.1. Однако, в зависимости от дистрибутива, может быть и больше. Посмотрим от каких пакетов на самом деле зависит пакет postgresql-12 (спойлер: 25 обязательных пакетов и 1 рекомендованный):
Наличие или отсутствие тех или иных пакетов, различные версии и другие факторы напрямую влияют на стабильность работы PostgreSQL. Используя контейнеризацию, возможные конфликты несовместимости нивелируются, т.к. все необходимые зависимости уже будут находиться в среде контейнера. Если загрузить готовый образ контейнера с ресурса Docker Hub (об этом ниже в статье), мы получим протестированную на совместимость и полностью готовую к работе среду.
И, наконец, отказоустойчивость. Если с сервером что-то случится, точно такой же контейнер может быть запущен на другом сервере с уже примонтированным хранилищем датафайлов.
Откроем консоль управления Selectel, перейдем в представление Облачная платформа и нажмем на кнопку Создать сервер.
Далее вводим имя сервера, выбираем образ операционной системы (остановимся на Ubuntu 20.04 LTS 64-bit) и фиксированную конфигурацию сервера с 2 vCPU и 4 ГБ RAM. Объем дискового пространства диска установим в 20 ГБ. Еще раз проверяем конфигурацию сервера и нажимаем Создать.
Проверим сетевые настройки, копируем пароль для root и удостоверимся в нижней части экрана, что все настройки корректны. Нажмем кнопку Создать.
Подождем минуту или две пока сервер не перейдет в состояние Active.
Теперь можем приступать к установке PostgreSQL в Docker. Поехали!
Как установить PostgreSQL в Docker из образа
Перед началом работы с PostgreSQL в контейнере Docker, установим сам Docker. Предварительно, добавим ключ для работы с репозиторием Docker Hub:
Добавим этот репозиторий в локальный список репозиториев и установим Docker:
Запустим демон Docker и активируем его автозапуск:
Поскольку за пределами жизненного цикла контейнера не остается каких либо данных, на файловой системе сервера (или другом файловом хранилище) необходимо создать каталог для хранения данных, которые будут появятся в процессе работы экземпляра PostgreSQL.
Чтобы получить из репозитория Docker Hub готовый образ контейнера с PostgreSQL, выполним следующую команду:
Теперь все готово к запуску.
Как запустить контейнер PostgreSQL
Выполним команду docker с ключом run:
Если возникла ошибка вида: «Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in use.», то следует вначале посмотреть какой процесс задействует порт 5432:
Затем прибить” процесс по его PID и вновь выполнить запуск Docker-контейнера:
Разберем ключи, которые мы использовали для запуска контейнера:
Как подключиться к PostgreSQL в контейнере
После успешного запуска контейнера с PostgreSQL, попробуем к нему подключиться при помощи утилиты psql. Установим ее из пакета postgresql-client:
Теперь можно подключиться и выполнить тестовый SQL-запрос:
Если появилось приглашение к вводу запроса, значит все действия были выполнены правильно.
Еще один вариант подключиться к базе данных, не устанавливая дополнительных утилит — подключиться непосредственно к Docker-контейнеру. Для этого выполним команду docker exec с дополнительными ключами:
Приглашение к вводу запроса будет означать корректность ввода команды. Разберем ключи, которые мы использовали для выполнения команды:
Теперь попробуем создать новую таблицу, добавить в нее данные и выполнить запрос:
Чтобы остановить запущенный контейнер выполним docker stop и укажем имя контейнера:
Файлы и процессы, созданные контейнером, принадлежат пользователю postgres, который является внутренним по отношению к контейнеру. В отсутствие пространства имен пользователей внутри контейнера, UID и GID в контейнере могут иметь произвольное значение. На самом сервере этим UID и GID могут соответствовать привилегированные пользователи или группы соответственно.
Например, пользователь на хосте с тем же UID или GID, что и пользователь postgres в контейнере, сможет получить доступ к данным в различных каталогах хоста, а также сможет завершить любой запущенный процесс. Чтобы избежать такой бреши в безопасности, укажем при запуске контейнера специализированные переменные USERMAP_UID и USERMAP_GID:
Как запустить PostgreSQL в контейнере в составе docker-compose
Еще одним вариантом запуска PostgreSQL в Docker-контейнере, является запуск контейнера с базой данных в составе docker-compose. В первую очередь, создадим соответствующий yml-файл:
Затем установим docker-compose:
Теперь запустим контейнер:
Ключ -d указывает, что docker-compose должен быть запущен в в фоновом режиме (вернет управление после его запуска).
Проверим возможность подключения к базе данных:
Появление приглашения к вводу команд для PostgreSQL означает корректность выполненных настроек.
Чтобы остановить запущенный контейнер, выполним docker-compose stop:
Заключение
Мы рассказали о работе с базой данных PostgreSQL в контейнере Docker, запуске, выполнении запросов и остановке. Как и говорили в начале статьи, работа с контейнеризованной в Docker базой данных упрощает процесс разработки и администрирование. Контейнеры могут быть легко перезапущены на другом сервере и сервис, предоставляемый базой данных, не прервется.
Spring Boot + PostgreSQL + JS в Doсker
В этой статье покажу, как поднять в Docker-контейнере приложение, состоящее из трех частей:
Приложение можно скачать тут.
Оно состоит из одного контроллера и одного html и js-файла, позволяющего выводить и добавлять животных. Животные хранятся в базе.

Установка Docker
Чтобы развернуть приложение в Docker, для начала нужно установить Docker на компьютер. В Window 7 это проблематично, в Windows 10 и других ОС вполне возможно.
Чтобы убедиться, что Docker установлен, выполните из командной строки:
Будет выведена версия Docker.
Теперь можно выполнять различные команды, которые билдят образы, запускают контейнеры и удаляют их все.
PostreSQL в контейнере
Одна из причин, почему Java-разработчику полезен Docker, это то, что можно не устанавливать различное дополнительное ПО. Например, базы данных различных версий. Ведь потом их придется удалять, остаются артефакты. Все это нежелательно, да и долго. С Docker проще.Например, чтобы испытать работу приложения с базой данных PostgreSQL 12 версии, можно не устанавливать ее на компьютер, а поднять в Docker-контейнере.
Для этого из командной строки запустим контейнер с базой:
Теперь с базой можно соединиться по такому url:

Разберем строку выше. Она поднимает контейнер из образа PostgreSQL:
Параметры команды
postgres:12-alpine — это имя образа. Готовые образы лежат на Docker Hub, там есть разные версии базы. При запуске контейнера образ сначала загружается оттуда, если его нет на компьютере локально.
—name some-postgres — задает имя контейнера. Все контейнеры, которые есть локально, можно просмотреть с помощью команды docker ps —all.
db-data — название volume, то есть того места на нашем диске, где реально будет храниться база из контейнера. Если не задавать volume, то при каждом новом запуске контейнера будет создаваться новый volume, и данные в базе для нас окажутся как бы не сохраненные. А с volume они будут сохраняться. Через двоеточие указан путь внутри контейнера, которому соответствует volume.
-p 5434:5432 — указан порт на локальной машине 5434, которому соответствует порт внутри контейнера 5432. То есть выставляем наружу порт контейнера 5432, чтобы присоединяться к базе снаружи через порт нашего локального компьютера 5434 (выбран другой порт (не 5432) чтобы не было конфликтов с локально установленной базой, если она есть).
Таким образом, мы соединились с базой со вкладки Databases редактора Intellij Idea. Так же можно соединяться и из приложения, не устанавливая базу на компьютер, а запуская любую ее версию в контейнере.
Файл docker-compose.yml
Обычно приложение состоит из нескольких компонентов, которые зависят друг от друга, но могут быть запущены изолированно на разных машинах. Например, Spring Boot приложение, предоставляющее REST API, PostgreSQL и фронтэнд на сервере Nginx. Наш пример именно такой. Для такой связки удобно применить docker-compose — это и команда, и файл.
Файл docker-compose.yml представлен ниже:
services — ключевое слово, под ним перечислены папки, в которых лежат три части нашего проекта: app, js, postgres.

docker-compose.yml лежит в корне иерархии рядом с папкой services, в которой перечислены сервисы — то есть компоненты, из который состоит наш проект.
Сервис Postgres: база данных PostgreSQL
Мы уже запускали postgres-контейнер из командной строки. Теперь все параметры вынесены из командной строки в файл docker-compose.yml — переменные среды, volume, порты. Копирую фрагмент этого файла:
Кстати, volume с именем db-data создается отдельной строкой в конце файла:
Обратите внимание, что каждого сервиса указан Dockerfile (файл для сборки образа):
для Postgres он лежит в папке services/postgres (см. скриншот выше). Его содержимое предельно кратко:
Строка выше означает, что мы просто берем готовый образ postgres:12-alpine и ничего к нему не добавляем.
Кстати, порты, указанные в docker-compose.yml:
можно и не выставлять, ведь к базе будем подключаться не мы с localhost, а Spring Boot из соседнего контейнера. А запись выше именно для доступа с локальной машины.
Другие образы будут чуть сложнее.
Сервис App: Spring Boot приложение
Скопирую фрагмент из docker-compose.yml, касающийся приложения Spring Boot:
Рассмотрим, из чего он состоит.
Порты
Порты указаны так же, как в сервисе postgres, только теперь на указанном порту запущен не сервер базы данных, а http-сервер. Порту 8091 контейнера соответствует порт 8091 нашего компьютера.
Зависимость
Тут сказано, что наш сервис зависит от сервиса postgres — это означает, что сначала запускается сервис postgres, а потом сервис app.
Имя образа
image: ‘my-java-app’ дает название образу.
Переменные среды
В environment перечислены переменные среды, к которым наше Spring Boot приложение имеет доступ. Мы их прописываем в application.yml приложения таким образом (через двоеточие стоит значение по умолчанию, которое используется в случае, если переменной окружения нет; у меня это просто значения для локального запуска без контейнера):
Доступ из одного контейнера в другой
Обратите внимание, что доступ из одного контейнера к другому происходит по имени сервиса. То есть к базе данных мы обращаемся не по localhost, а по postgres:
Это значение мы указывали выше в docker-compose.yml в переменной среды SPRING_DATASOURCE_URL.
Dockerfile.development
Сервис app использует такой докер-файл:
Тут мы собираем образ на основе готового образа openjdk, задаем рабочую папку и копируем в нее наше приложение docker-demo-0.0.1-SNAPSHOT.jar (оно лежит рядом docker-файлом см. структуру папок выше — надо его сюда скопировать) под именем app.jar. А затем запускаем приложение с помощью команды:
Наконец, рассмотрим последний компонент.
Сервис JS: JavaScript приложение
Тут все аналогично, только заданы другие порты и другое имя образа:
Dockerfile.development
Докер-файл у сервиса js такой:
То есть мы собираем образ на основе готового образа nginx:alpine. Затем копируем в папку сервера Nginx /usr/share/nginx/html файлы из папки dist (лежит рядом с докер-файлом, содержит html и js-файлы).
Как всё запустить: команда docker-compose
Наконец, из папки с файлом docker-compose.yml надо выполнить команду:
Команда выше и построит образы, и запустит на их основе контейнеры.
Теперь в браузере по адресу
будет доступно наше приложение.
Чтобы остановить и удалить контейнеры, выполним команду:
Если нужно удалить и volume с данными, делаем так:
Если вы сохраняли каких-то животных в приложении, то после этой команды при следующем запуске приложения их не будет.
Spring Boot + PostgreSQL + JS в Doсker: 2 комментария
Спасибо, то что надо!
Очень доступно и без ерунды.
Как использовать Django, PostgreSQL и Docker
В этом уроке мы создадим новый проект Django, используя Docker и PostgreSQL. Django поставляется со встроенной поддержкой SQLite, но даже для локальной разработки лучше использовать «настоящую» базу данных, такую как PostgreSQL, которая соответствует производственной.
Можно запускать PostgreSQL локально, используя такой инструмент, как Postgres.app, однако сегодня среди многих разработчиков предпочтительным является использование Docker, инструмента для создания изолированных операционных систем. Проще всего представлять это как виртуальную среду, которая содержит все необходимое для нашего проекта Django: зависимости, базы данных, службы кэширования и любые другие необходимые инструменты.
Основная причина использования Docker заключается в том, что он полностью устраняет любые проблемы, связанные с локальной разработкой. Вместо того, чтобы беспокоиться о том, какие программные пакеты установлены или работают с локальной базой данных вместе с проектом, вы просто запускаете образ Docker всего проекта. Лучше всего то, что этим можно поделиться в группах и значительно упростить разработку команды.
Инсталяция Docker
Первым шагом является установка настольного приложения Docker для вашего локального компьютера:
Первоначальная загрузка Docker может занять некоторое время для загрузки.
После завершения установки Docker мы можем подтвердить, что запущена правильная версия. В вашем терминале запустите команду docker —version.
Docker Compose — это дополнительный инструмент, который автоматически включается в загрузку Docker для Mac и Windows. Однако, если вы используете Linux, вам нужно будет добавить его вручную. Вы можете сделать это, выполнив команду sudo pip install docker-compose после завершения установки Docker.
Проект Django
Создайте новый каталог проекта вместе с новым проектом Django:
Перейдите по адресу http://localhost:8000/ для просмотра экрана приветствия Django. Остановите сервер и выйдите из виртуальной среды. Теперь у нас есть простой проект Django для работы.
Создайте файл requirements.txt в каталоге app и добавьте Django в качестве зависимости:
Поскольку мы перейдем будем использовать Postgres в качестве БД для проекта, удалите файл db.sqlite3 из каталога app.
Ваша директория проекта должна выглядеть так:
Docker
Надеюсь, Docker завершил установку к этому моменту. Чтобы убедиться, что установка прошла успешно, закройте локальный сервер с помощью Control + c, а затем введите в командной строке docker run hello-world. Вы должны увидеть ответ вроде этого:
Образы и контейнеры
В Docker есть две важные концепции: образы (images) и контейнеры (containers).
Другими словами, образ (image) описывает, что произойдет, а контейнер (container) — это то, что фактически выполняется.
Для настройки образов и контейнеров в Docker мы используем два файла: Dockerfile и docker-compose.yml.
Dockerfile содержит список инструкций для образа, иначе говоря, что на самом деле происходит в среде контейнера.
Создадим новый файл Dockerfile.
Затем добавьте следующий код в него.
В верхней строке мы используем официальный образ Docker для Python 3.8. Далее мы создаем две переменные окружения.
Затем мы устанавливаем рабочий каталог вместе с двумя переменными среды:
Наконец, мы обновили pip, скопировали файл requirements.txt, установили зависимости и скопировали сам проект Django.
Мы не можем запустить Docker-контейнер, пока у нас не будет созданного образа, поэтому давайте сделаем это, создав его.
В случае успеха у вас должно быть что то типа такого.
Далее нам нужен новый файл docker-compose.yml. Он говорит Docker, как запустить наши Docker-контейнеры. У нас будут 2 контейнера. Один для базы, другой для приложения.
С начало добавим в него один контейнер для приложения:
Обновите переменные SECRET_KEY, DEBUG и ALLOWED_HOSTS в settings.py:
Затем создайте файл .env.dev в корне проекта для хранения переменных среды для разработки:
Собираем образ командой:
Как только образ будет собран, запускаем контейнер:
Далее нужно перейти по адресу http://localhost:8000/, чтобы снова увидеть экран приветствия и убедиться что все работает.
Проверьте наличие ошибок в журналах, если это не работает, через команду:
Подключаем PostgreSQL
Чтобы настроить Postgres, нам нужно добавить новый сервис в файл docker-compose.yml, обновить настройки Django и установить Psycopg2.
Сначала добавим новый сервис db в docker-compose.yml:
Чтобы сохранить данные за пределами контейнера, мы настроили том (volume). Этот конфиг будет связывать postgres_data с каталогом «/var/lib/postgresql/data/» в контейнере.
Мы также добавили ключ среды, чтобы определить имя для базы данных по умолчанию и установить имя пользователя и пароль.
Поэтому внесем соотвествующие изменения в файл .env.dev :
Затем обновите файл settings.py, чтобы указать, что мы будем использовать PostgreSQL, а не SQLite.
Здесь база данных настраивается на основе переменных среды, которые мы только что определили. Обратите внимание на значения по умолчанию.
Внесем изменения в Dockerfile, чтобы установить соответствующие пакеты, необходимые для Psycopg2:
Добавьте Psycopg2 в файл requirements.txt:
Соберем новый образ и запустим два контейнера:
Если получите следующую ошибку:
Убедимся, что все таблицы Django по умолчанию были созданы:
Вы также можете проверить, что том (volume) был создан, запустив команду:
Вы должны увидеть что-то похожее на:
Затем добавим файл entrypoint.sh в каталог проекта app, чтобы проверить работоспособность Postgres перед применением миграций и запуском сервера разработки Django:
Обновим локальные права доступа к файлу:
Затем обновим Dockerfile, чтобы скопировать файл entrypoint.sh и запустите его как команду точки входа Docker:
Добавим переменную среды DATABASE в .env.dev:
Проверьте все снова:
Примечание
Во-первых, несмотря на добавление Postgres, мы все равно можем создать независимый образ Docker для Django, если для переменной среды DATABASE не задано значение postgres. Чтобы проверить, создайте новый образ и затем запустите новый контейнер:
Вы должны увидеть страницу приветствия по адресу http://localhost:8006.
Во-вторых, вы можете закомментировать команды очистки (flush) и миграции (migrate) базы данных в сценарии entrypoint.sh, чтобы они не запускались при каждом запуске или перезапуске контейнера:
Вместо этого вы можете запустить их вручную, после того, как контейнеры запустаться, вот так:
Небольшой список команд Docker
Когда вы закончите, не можете погасить контейнер Docker.
Просто приостановить контейнер
Запустить ранее остановленный контейнер
Что бы посмотреть работающие контейнеры
Что бы посмотреть вообще все контейнеры
Посмотреть список всех образов
Иногда может понадобиться зайти в работающий контейнер. Для этого нужно запустить команду запуска интерактивной оболочкой bash
Gunicorn
Двигаясь дальше, в производственную среду, давайте добавим Gunicorn, сервер WSGI промышленного уровня, в файл requirements.txt:
Поскольку мы все еще хотим использовать встроенный сервер Django для разработки, создайте новый файл compose под названием docker-compose.prod.yml для производственной среды:
Если у вас несколько сред, вы можете использовать конфигурационный файл docker-compose.override.yml. При таком подходе вы добавляете базовую конфигурацию в файл docker-compose.yml, а затем используете файл docker-compose.override.yml для переопределения этих параметров конфигурации в зависимости от среды.
Обратите внимание на команду command. Мы используем Gunicorn, а не сервер разработки Django. Мы также удалили том из web, поскольку он нам не нужен. Наконец, мы используем отдельные файлы переменных среды, чтобы определить переменные среды для обеих служб, которые будут переданы в контейнер во время выполнения.
Затем соберем производственные образы и запустим контейнеры:
Убедимся, что база данных hello_django_prod была создана вместе с таблицами Django по умолчанию. Протестируем страницу администратора по адресу http://localhost:8000/admin. Статические файлы больше не загружаются. Это ожидается, так как режим отладки выключен. Мы исправим это в ближайшее время.
Производственный Dockerfile
Вы заметили, что мы все еще выполняем очистку базы данных (flush)(которая очищает базу данных) и переносим команды при каждом запуске контейнера? Это хорошо в разработке, но давайте создадим новый файл точки входа для производства.
Обновим права доступа к файлу:
Чтобы использовать этот файл, создайте новый Dockerfile с именем Dockerfile.prod для использования с производственными сборками:
Здесь мы использовали многоэтапную сборку (multi-stage build) Docker, чтобы уменьшить окончательный размер образа. По сути, builder — это временный образ, которое используется для сборки Python. Затем он копируются в конечный производственный образ, а образ builder отбрасывается.
Вы заметили, что мы создали пользователя без полномочий root? По умолчанию Docker запускает контейнерные процессы как root внутри контейнера. Это плохая практика, поскольку злоумышленники могут получить root-доступ к хосту Docker, если им удастся вырваться из контейнера. Если вы root в контейнере, вы будете root на хосте.
Обновите web сервис в файле docker-compose.prod.yml для сборки с помощью Dockerfile.prod:
Проверим как все работает:
Nginx
Далее, давайте добавим Nginx, чтобы он действовал как обратный прокси-сервер для Gunicorn для обработки клиентских запросов, а также для обслуживания статических файлов.
Добавим сервис nginx в docker-compose.prod.yml:
Затем в локальном корне проекта создайте следующие файлы и папки:
Затем обновим сервис web в docker-compose.prod.yml, заменить ports на expose :
Теперь порт 8000 открыт только для других сервисов Docker. И это порт больше не будет опубликован на хост-машине.
Проверяем как это работает
Убедимся, что приложение запущено и работает по адресу http://localhost:1337.
Структура вашего проекта теперь должна выглядеть так:
Теперь снова остановим контейнеры:
Поскольку Gunicorn является сервером приложений, он не будет обслуживать статические файлы. Итак, настроим обработку статических и мультимедийных файлов
Статические файлы
Development
Теперь любой запрос к http://localhost:8000/staticfiles/ * будет обслуживаться из каталога «staticfiles».
Чтобы проверить, сначала песоберем образы и запустим новые контейнеры в обычном режиме. Убедимся, что статические файлы по-прежнему правильно обслуживаются по адресу http://localhost:8000/admin.
Production
Для производственной среды добавьте volume в web и службы nginx в docker-compose.prod.yml, чтобы каждый контейнер имел общий каталог с именем «staticfiles»:
Нам также необходимо создать папку «/home/app/web/staticfiles» в Dockerfile.prod:
Почему это необходимо?
Docker Compose обычно монтирует именованные тома как root. И поскольку мы используем пользователя без полномочий root, мы получим ошибку отказа в разрешении при запуске команды collectstatic, если каталог еще не существует
Чтобы обойти это, вы можете:
Мы использовали первое.
Затем обновите конфигурацию Nginx для маршрутизации запросов статических файлов в папку «staticfiles»:
Теперь все запросы к http://localhost:1337/staticfiles/ * будут обслуживаться из каталога «staticfiles».
Перейдите по адресу http://localhost:1337/admin и убедитесь, что статические ресурсы загружаются правильно.
Далее снова остановим контейнеры:
Media файлы
Чтобы проверить обработку мультимедийных файлов, начните с создания нового модуля Django:
Добавим новый модуль в INSTALLED_APPS в settings.py:
Внесем изменения в следующие файлы
Добавим директорию «templates», в каталог «app/upload», и добавим новый шаблон upload.html:
Development
Теперь у вас должна быть возможность загзулить файл на http://localhost:8000/, и затем увидеть этот файл на http://localhost:8000/mediafiles/IMAGE_FILE_NAME.
Production
Для производственной среды добавим новый том volume в сервисы web и nginx :
Создаим каталог /home/app/web/mediafiles в Dockerfile.prod:
Снова обновим конфиг Nginx:
Далее перезапустим контейнеры
Проверим как все работает:
Заключение
В этой статье мы рассмотрели, как создать контейнер для веб-приложения Django с Postgres. Мы также создали готовый к работе файл Docker Compose, который добавляет Gunicorn и Nginx в нашу конфигурацию для обработки статических и мультимедийных файлов. Теперь вы можете проверить производственную настройку локально.
С точки зрения фактического развертывания в производственной среде, вы, вероятно, захотите использовать:
Для других советов работы с производственной средой, см эту дисскусию.






















