Django-окружение и среда Postgres для docker

Я использую пакет django-environ для своего проекта Django. Я указал url БД в файле .env, который выглядит следующим образом: DATABASE_URL=psql://dbuser:dbpassword@dbhost:dbport/dbname

Мои настройки БД в settings.py:

DATABASES = {
    "default": env.db(),
}

Пока у меня нет проблем.

Затем я создал docker-compose.yml, где указал, что мой проект использует базу данных Postgres, т.е.:

version: '3.8'

services:
  ...
    db
      image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=???
      - POSTGRES_PASSWORD=???
      - POSTGRES_DB=???
      - "POSTGRES_HOST_AUTH_METHOD=trust"

Теперь я немного запутался.

Как мне предоставить эти POSTGRES_* env. переменные там? Нужно ли мне предоставить их как отдельные переменные вместе с DATABASE_URL в моем .env файле? Если да, то как лучше всего это сделать? Я стремлюсь избежать дублирования в настройках.

Вы можете использовать расширение переменных в вашем .env файле. Что-то вроде

DB_NAME=dbname
DB_USER=dbuser
DB_PASSWORD=dbpassword
DATABASE_URL=psql://$DB_USER:$DB_PASSWORD@dbhost:dbport/$DB_NAME

и затем что-то вроде этого в вашем файле compose

services:
  postgresdb:
    container_name: projectname_db
    image: postgres:15
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    ports:
      - "127.0.0.1:5432:5432"
...

Я не совсем знаком с django-environ, но это должно работать

Очевидно, django-environ не поддерживает расширение переменных (начиная с версии 0.10.0), поэтому я нашел способ прописать отдельные опции вместо использования env.db()

Настройки Django

DATABASES = {
  "default": {
     # ...
     "NAME": env("DB_NAME"),
     "USER": env("DB_USER"),
     "PASSWORD": env("DB_PASSWORD"),
  },
}

Docker Compose

version: '3.8'

services:
  # ...
  db:
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}

Объявите vars в файле .env, а затем ссылайтесь на этот файл в атрибуте env_file контейнера Django в файле docker-compose. В этом случае файл настроек Django сможет получить к ним доступ с помощью os.environ.get(). Вары Env в атрибуте environment в файле docker-compose не интерполируются из файла .env. Они будут интерполированы туда только в том случае, если эти переменные экспортированы в оболочку, из которой запускается файл compose. Мне помогло просмотреть эти документы, когда я столкнулся с той же проблемой: Приоритет переменных окружения в Docker Compose.

<<<Пример файла

.env:

DB_NAME=my_database
DB_USER=postgres_user
DB_PASSWORD=1234567

В блоке Django в файле docker-compose сделайте ссылку на ваш env-файл:

# ....
    env_file:
      - ./.my_env_file
# ...

Настройки Django:

import os
    
    DATABASES = {
        'default': {
           # ...

            "POSTGRES_DB": os.environ.get("DB_NAME"),
            "POSTGRES_USER": os.environ.get("DB_USER"),
            "POSTGRES_PASSWORD": os.environ.get("DB_PASSWORD")

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