0

I've a docker image with django 3.1 and postgresql.

In the docker-compose.yml I wrote:

version: '3'

services:
  app:
   build:
     context: .
   ports:
     - "8001:8001"
   volumes:
     - ./app:/app
   command: >
     sh -c "python manage.py runserver 0.0.0.0:8001"
   environment:
     - DB_HOST=db
     - DB_NAME=app
     - DB_USER=postgres
     - DB_PASS=password

   depends_on:
     - db

  db:
    image: postgres:10-alpine
    environment:
      - POSTGRES_DB=app
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password

In the Django app's settings.py I read the database password from the .txt file excluded from the .git

...

DB_PASSWORD = ''
with open('database_password.txt') as f:
    DB_PASSWORD = f.read().strip()

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'HOST': os.environ.get('DB_HOST'),
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': DB_PASSWORD,
    }
}
...

What is the best practice to make Django and Docker securely read the same password from the same place?

The most suitable information about this I found here: https://medium.com/swlh/setting-up-a-secure-django-project-repository-with-docker-and-django-environ-4af72ce037f0

The author offers to use the django-environ package for django. The docker part in this article descibed like this:

If you specifed a different user and password in the DATABASE_URL variable in the .env file above, you should include them here (although this will compromise the security of the database, as the docker-compose.yml file will be committed to the repository). When it comes time to deploy the project, create a separate docker-compose file that will not be committed.

And it's not very clear to me.

1 Answer 1

2

I use almost the same solution, but rather have the environment variables in a separate file db.env which is in .gitignore and only readable by root.

The key is in the docker-compose env_file drirective.

Now the docker-compose.yml looks something like:

version: '3'

services:
  app:
   build:
     context: .
   ports:
     - "8001:8001"
   volumes:
     - ./app:/app
   env_file:
      - db.env
   command: >
     sh -c "python manage.py runserver 0.0.0.0:8001"
   depends_on:
     - db

  db:
    image: postgres:10-alpine
  env_file:
      - db.env

And in db.env:

DB_HOST=db
DB_NAME=app
DB_USER=postgres
DB_PASS=password

Finally in Django settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'HOST': os.environ.get('DB_HOST', 'localhost'),
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
    }
}

This solves the issue of keeping private information out of GIT but you will need to find a solution to deploy the .env files in another way and make sure these can not leak in turn. For a simple single host set-up this could be done manually.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.