Теперь, когда вы знаете о том, для чего мы собираемся использовать Docker Compose, пришло время создать ваше первое клиент-серверное приложение с использованием этого инструмента.
В этом разделе разберемся с тем, что такое Docker Compose и как он работает на реальном небольшом проекте — положим Django и PostgreSQL в контейнеры, так чтобы они работали как одно целое. Для сборки кластера контейнеров используется docker-compose.yml.
Docker-compose.yml — конфигурационный файл в YAML-формате, описывающий логику запуска и взаимодействия контейнеров между собой и внешним миром. В сущности инструкции заложенные в docker-compose.yml по логике работы идентичны ключам команды docker run.
Для запуска контейнеров через docker-compose используются следующие команды:
docker-compose build: собрать проект
docker-compose up -d: запустить проект
docker-compose down: остановить проект
docker-compose logs -f [service name]: посмотреть логи сервиса
docker-compose ps: вывести список контейнеров
docker-compose exec [service name] [command]: выполнить команду в контейнере
docker-compose images: вывести список образов
Подготовка проекта к Docker Compose
Первым делом нам необходимо удалить команды из Dockerfile которые открывают доступ к порту и выполняют команды запуска:
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Далее вынесем некоторые настройки в отдельный файл. Как мы можем прочитать из документации, в основном, что делает python-dotenv, это считывает пары ключ-значение из файла .env и устанавливает их как переменные среды для последующего извлечения. Мы уже использовали его в курсе "Django 4 для начинающих".
Для этого необходимо обновить список зависимостей requirements.txt, добавив туда следующую строку:
python-dotenv==1.0.0
И отредактировать файл настроек settings.py, добавить в самое начала файла следующий код:
from dotenv import load_dotenv
import os
load_dotenv()
Далее изменим нужные переменные:
SECRET_KEY = str(os.getenv('SECRET_KEY'))
DEBUG = str(os.getenv('DEBUG'))
ALLOWED_HOSTS = str(os.getenv('DJANGO_ALLOWED_HOSTS')).split(" ")
CACHES = {
'default': {
'BACKEND': str(os.getenv('CACHES_BACKEND')),
'LOCATION': str(os.getenv('CACHES_LOCATION')),
}
}
INTERNAL_IPS = str(os.getenv('INTERNAL_IPS')).split(" ")
И добавим данную строку:
CSRF_TRUSTED_ORIGINS = str(os.getenv('CSRF_TRUSTED_ORIGINS')).split(" ")
Теперь изменим расположение нашего проекта. Для этого в корне создадим папку app, и переместим в неё проект вместе с Dockerfile.
А в файл .env добавим следующий код:
DEBUG = True
SECRET_KEY = 'django-insecure-xxxxxxxxxxxx'
DJANGO_ALLOWED_HOSTS = '127.0.0.1'
CSRF_TRUSTED_ORIGINS = 'http://127.0.0.1'
CACHES_BACKEND = 'django.core.cache.backends.locmem.LocMemCache'
CACHES_LOCATION = 'unique-snowflake'
INTERNAL_IPS = '127.0.0.1'
Настройки в файле .env говорят, что сервер будет запускаться в режиме отладки и принимать подключения с 127.0.0.1.
Теперь, каждый раз выполняя сборку контейнеров, у нас будут выполняться следующий процесс:
- При запуске контейнера будет читаться файл
.envсодержащий какие-то значения; - Значения из файла будут помещены как глобальные переменные проекта (переменные окружения);
- Django, через библиотеку
os.getenv, читает некоторые переменные из окружения и подставляет где нужно.
Таким образом, если мы захотим поменять настройки, нам не придется еще раз редактировать settings.py или docker-compose.yml.
Затем добавьте файл docker-compose.yml в корень проекта:
version: '3.8'
services:
web:
# Берем Dockerfile из каталога app
build: ./app
# Запускаем тестовый сервер
command: python manage.py runserver 0.0.0.0:8000
# куда будут помещены данные из каталога app
volumes:
- ./app/:/usr/src/app/
# Открываем порт 8000 внутри и снаружи
ports:
- 8000:8000
# Файл содержащий переменные для контейнера
env_file:
- ./.env
Обратите внимание на значение version. Если вы используете старую версию Docker - вам может потребоваться ее изменить.
В итоге мы получаем следующую файловую структуру:
Внутри папки app находится наш Django проект, его Dockerfile и requirements.txt.
Проверим файл settings.py, а именно папку наших шаблонов, при перемещении проекта PyCharm автоматически меняет путь:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
STATICFILES_DIRS = [BASE_DIR / 'static']
Создадим файл .dockerignore в корне нашего проекта, чтобы исключить лишние папки и файлы:
venv
.idea
Перед выполнением следующих шагов проверьте в Docker Desktop запущенные контейнеры, их необходимо остановить. Теперь попробуем создать наш образ Docker Compose:
docker-compose build
После создания образа запустите контейнер:
docker-compose up -d
Опция -d или --detach используется для создания и запуска контейнеров в фоновом режиме.
Перейдите на http://127.0.0.1:8000, чтобы убедиться что наш Django проект работает:
Теперь мы можем открыть Docker Desktop и посмотреть на наши контейнеры:
В следующем шаге мы добавим сервис PostgreSQL к нашему проекту.