1

I am using django-environ package for my Django project. I provided the DB url in the .env file, which looks like this: DATABASE_URL=psql://dbuser:dbpassword@dbhost:dbport/dbname

My DB settings in settings.py:

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

So far, I have no issues.

Then, I created a docker-compose.yml where I specified that my project uses Postgres database, i.e.:

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"

Now I am confused a little.

How do I provide these POSTGRES_* env. variables there? Do I need to provide them as separate variables alongside with the DATABASE_URL in my .env file? If yes, what's the best way do accomplish this? I aim to avoid duplication in my settings.

varnie
  • 2,523
  • 3
  • 35
  • 42

2 Answers2

1

You can use variable expansion in your .env file. Something like

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

and then something like this in your compose file

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"
...

I am not exactly familiar with django-environ but this should work

  • It doesn't work in my case. It says `ValueError: Port could not be cast to integer value as '$DB_PORT'` when I run it without docker. I haven't tested it with Docker setup though, will let you know a bit later! – varnie Feb 04 '23 at 14:28
  • I am guessing your django app isn't containerised? `django-environ` does not do variable expansion when parsing `.env` file while `docker compose` does while passing environment to containers. – janezicmatej Feb 04 '23 at 22:27
0

Apparently, django-environ doesn't support variable expansion (as of v0.10.0), so the way I found is to spell out the individual options instead of using env.db()

Django settings

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}

TheMonarch
  • 397
  • 4
  • 11