Search code examples
djangodockerdocker-composeenvironment-variablesdjango-environ

django-environ and Postgres environment for docker


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.


Solution

  • Declare the vars in your .env file and then reference the file in the env_file attribute of Django container in docker-compose file. This is where the Django settings file can access them with os.environ.get(). Env vars in the environment attribute in a docker-compose file do not interpolate from an .env file. They would only interpolate there if the vars were exported in the shell that the compose file is run from. It helped me to view these docs when experiencing the same issue: Environment variables precedence in Docker Compose.

    .my_env_file example:

    DB_NAME=my_database
    DB_USER=postgres_user
    DB_PASSWORD=1234567
    

    In Django block in docker-compose file, reference your env file:

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

    Django settings:

    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")
    
               # ...
            }
        }