Setting up Postgres DB backend

Installing dependencies in Dockerfile and keeping the Docker container small

1) To use postgres, we need the following python dependency


2) Before installing psycopg2, we have to run the dependency installs in Dockerfile.

3) We should also remove the unwanted dependencies to keep the docker container small. For eg, if we need gcc only for compiling and do not need it afterwards, gcc should be removed after installation.

Structure of Dockerfile

1) Install permanant and temporary dependencies in separate lines

2) Delete temporary dependencies after the required build is complete

# PERMANANT dependences
# apk is the package manager that comes with alpine
# --update : update registry before we add it
# --no-cache: Do not store index locally. Used to keep container small
RUN apk add --update --no-cache postgresql-client
# TEMPORARY dependencies. Needed only for installing
# --virtual: an alias which can be used to remove dependencies later
# Eg. We need gcc to compile the program but do not need it later
RUN apk add --update --no-cache --virtual .tmp-build-deps \
      gcc libc-dev linux-headers postgresql-dev

RUN pip install -r /requirements.txt

# Delete temporary dependencies
RUN apk del .tmp-build-deps

Running postgres in a separate container and adding its dependency to main container

We have to make the following changes in the docker-compose.yml and

1) Set up separate postgres service with image postgres:10-alpine

2) Set the environment variable to use postgres:10-alpine as specified in documentation

3) Map the database volume in a level above the docker-compose.yml file. Otherwise, build fails because of recusive search done by docker in child folders

      #database served as separate service
        image: postgres:10-alpine
          # dont have db in same level as docker-compose. otherwise build fails because of recursive search
          - ../postgres:/var/lib/postgresql/data
          - POSTGRES_DB=app
          - POSTGRES_USER=uname
          - POSTGRES_PASSWORD=password

3) Link the main service (app) to the database service using depends_on keyword

4) Set up environment variables in main service, so that it can be passed on to to reflect changes


    # These environments will be used in
      - DB_HOST=db
      - DB_NAME=app
      - DB_USER=uname
      - DB_PASS=password
      - db

5) In under DATABASES

# Database

        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'HOST': os.environ.get('DB_HOST'),
            'NAME': os.environ.get('DB_NAME'),
            'USER': os.environ.get('DB_USER'),
            'PASS': os.environ.get('DB_PASS'),