Files
blog/content/ru/docker-envs.md
2021-12-10 11:54:53 +04:00

6.6 KiB
Raw Blame History

title, description, position, category
title description position category
Разделение докера на среды. Как работать с несколькими docker-compose. 2 DevOps

Разделение докера на среды

Должен ли ты разделять среды докера в несколько docker-compose файлов? Определенно! В некоторых случаях невозможно разобраться что разработчики хотели сделать или почему ничего не работает. Настройка раздельных сред может стать настояшей мешаниной. В этой статье я покажу как настроить docker-compose и избежать миллиона проблем.

Как мы вообще можем разделить среды для локальной разработки и продовые? Отет прост: Требуется декомпозировать проект и создать отдельные файлы под каждую из сред или даже сервисов.

Это нормально, если у тебя будет больше 2-х docker-compose файлов.

Например:

deploy  
├── docker-compose.autotests.yml
├── docker-compose.db.yml  
├── docker-compose.dev.yml  
├── docker-compose.yml  
├── dockerfiles  
│   ├── api.Dockerfile  
│   └── front.Dockerfile  
└── scripts  
   ├── start-autotests.sh  
   ├── start-backend.sh
   └── start-migrations.sh

Как это работает?

Докер умеет работать с множеством docker-compose файлов одновременно. И мы можем использовать это для разделения сред.

Запуск таких конфигураций выглядит следующим образом:

docker-compose \
	-f "deploy/docker-compose.yml" \
	-f "deploy/docker-compose.db.yml" \
	-f "deploy/docker-compose.dev.yml" \
	up

В каждом из этих файлов определен какой-то кусок конфигурации, который не пересекается. Например в docker-compose.yml определено приложение и некоторые необходимые сервисы, а в остальных файлах добавляются сервисы или меняются значения предыдущих.

Наверное, тут проще показать на примере.

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

Для простоты примера создадим простецкий проект со следующей структурой:

proj
├── deploy
│   ├── docker-compose.yml  
│   └── dockerfiles  
│       └── script.Dockerfile  
└── script.py

Для начала напишем скрипт, который будет в центре всего.

from sys import argv # это аргуметы переданные в скрипт

def main():
	print("; ".join(argv[1:])) # выводит на экран все аргументы программы

if __name__ == "__main__":
	main()

После того, как скрипт готов и отлажен давайте завернем его в докер, создав Dockerfile.

from python:3.8 # asd

WORKDIR /app  
COPY script.py /app/script.py  
CMD python /app/script.py

Как вы видите, Dockerfile очень прост. Теперь добавим главный docker-compose.yml.

---
version: '3.7'  
  
services:  
  script:  
        build:  # Собираем приложение используя наш dockerfile.
            dockerfile: ./deploy/dockerfiles/script.Dockerfile  
            context: .  
        # Запускаем его с командой для продового запуска.
        command: python script.py this is prod

Теперь запустим всё это чудо.

d-test docker-compose \
        -f "./deploy/docker-compose.yml" \
        --project-directory "." \
        run --rm script

Вот что будет выведено на экран.

Creating d-test_script_run ... done
this; is; prod

Как мы видим, на экран вывелось сообщение, которое мы указали в нашем docker-compose.yml

А теперь для локальной разработки мы не будем ничего менять в нашем файле композиции, а создадим новый рядом.

---
version: '3.7'  
  
services:  
  script:
    command: python script.py this is dev

Теперь добавим ещё один файл в нашу команду запуска.

d-test docker-compose \
        -f "deploy/docker-compose.yml" \
        -f "deploy/docker-compose.dev.yml" \
        --project-directory "." \
        run --rm script

Вот что будет выведено на экран:

Creating d-test\_script\_run ... done  
this; is; dev

Как можно заметить, конфигурация запуска перезаписалась в порядке вызова.

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

Итоговая структура проекта:

proj
├── deploy  
│   ├── docker-compose.dev.yml  
│   ├── docker-compose.yml  
│   └── dockerfiles  
│       └── script.Dockerfile  
└── script.py

Где это применимо?

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