Как управлять несколькими средами разработки в рабочем процессе Django с помощью Docker compose

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

Некоторые описания моих исходных данных:

  1. У меня было около 20 вариантов env, но некоторые из них были разделены между средами.
  2. Я хотел сделать это с минимальным воздействием, насколько это возможно.

Во-первых, команда помощи docker-compose

Первым делом я запустил простой docker-compose --help, и он вернул следующее:

Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
# more not necessary stuff
  --env-file PATH             Specify an alternate environment file

Я пошел с флагом -f, потому что я также хотел запустить несколько образов докера для разработки. Используя флаг -f, я мог создать базовый файл compose с общими env-переменными (docker-compose.yml) и еще один для каждой среды (prod.yml и dev.yml).

Итак, я пошел дальше. Я сохранил общие переменные внутри docker-compose.yml и добавил конкретные переменные и конфигурацию в prod.yml и dev.yml

docker-compose.yml:

version: "3"

services:
  app:
    build:
      context: .
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    command: >
      sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    environment:
      - myvar1=myvar1
      - myvar2=myvar2
      ...
      - myvarx=myvarx

Поскольку я собираюсь подключиться к удаленному RDS и удаленному Redis, в моем prod.yml мне не нужно определять образ Postgres или Redis:


version: "3"
services:
  app:
    environment:
      # DB connections
      - DB_HOST=my-host
      - DB_NAME=db-name
      - DB_USER=db-user
      - DB_PASS=mysupersecurepassword
      ...

Для dev.yml я добавил образ базы данных Postgres и образ Redis:

version: "3"

services:
  app:
    depends_on:
      - db
      - redis
    environment:
      # Basics
      - DEBUG=True
      # DB connections
      - DB_HOST=db
      - DB_NAME=app
      - DB_USER=postgres
      - DB_PASS=supersecretpassword
      ...
  db:
    image: postgres:10-alpine
    environment:
      - POSTGRES_DB=app
      - POSRGRES_USER=postgres
      - POSTGRES_PASSWORD=supersecretpassword
    links:
      - redis:redis

  redis:
    image: redis:5.0.7
    expose:
      - "6379"

И чтобы запустить его между средами, все, что мне нужно сделать, это:

# Для продакшена
docker-compose -f docker-compose.yml -f prod.yml up 

# Для разработки
docker-compose -f docker-compose.yml -f dev.yml up 

Это всё! У меня есть несколько файлов docker-compose для всех моих сред, но я могу пойти еще дальше.

Улучшение решения

Улучшение базового файла docker-compose.yml

Мне понравилось, как это выглядело, но я знал, что могу пойти дальше. Куча переменных внутри базового docker-compose.yml выглядела странно и делала файл немного нечитаемым. Итак, еще раз, я пошел к документации docker-compose и нашел то, что мне нужно: env файлы в docker-compose.

Поэтому я создал файл с именем globals.env и переместил все глобальные переменные env в этот файл:

myvar1=myvar1
mivar2=myvar2
...

И в файле docker-compose.yml я назвал файл globals.env:

  app:
    env_file: globals.env

Это конечный результат:

version: "3"

services:
  app:
    build:
      context: .
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    command: >
      sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    env_file: globals.env

Улучшение команды запуска

Как я упоминал ранее, я хотел добиться как можно меньшего эффекта, и docker-compose -f docker-compose.yml -f envfile.yml up был для меня немного длинным. Поэтому я создал пару файлов bash, чтобы облегчить прием файлов docker-compose:

prod:

#!/usr/bin/env bash
# Run django as production
docker-compose -f docker-compose.yml -f prod.yml "$@"

dev:

#!/usr/bin/env bash
# Run django as development
docker-compose -f docker-compose.yml -f dev.yml "$@"

The "$@" means “Append all extra arguments here”, so if I ran the dev command with the up -d arguments, the full command would be docker-compose -f docker-compose.yml -f development.yml up -d, so it is exactly what I wanted

«$@» означает «Добавить все дополнительные аргументы здесь», поэтому, если бы я выполнил команду dev с аргументами up -d, полная команда была бы docker-compose -f docker-compose.yml -f development.yml up -d, так это именно то, что я хотел

Быстрое управление разрешениями:

chmod +x prod dev 

И теперь я могу запустить свою среду как:

./dev up
./prod up

Все хорошо?

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

https://blog.rogs.me/2020/05/how-i-manage-multiple-development-environments-in-my-django-workflow-using-docker-compose/

Вернуться на верх