Analytics Vidhya
Published in

Analytics Vidhya

Django with Docker and Docker Compose (Python part 2)

In this part of the article introduce the database service in docker composer. Then I have to modify some configuration of Django to make a project compatible with Local Development and Docker Development and deployment also. Show the migration process of the Local environment and the Docker environment. Provide a brief introduction about Django Interactive Shell for development use.

The part of the article series

  1. Django with Docker and Docker Compose (Python part 1)

The files which will be modified to connected PostgreSQL docker service, the structure is provided below.

django-docker
└──
app
│ ├── main
│ │ ├── model.py
│ ├── docker-entrypoint.sh
│ ├── Dockerfile
└──
env
│ ├── django.env
│ ├── postgresql.env
└── docker-compose.yml

Check if the main the module is project-wide available in setting.py , if not available, find the INSTALLED_APPS array in setting.py file, add it like below code snippet

# django-docker/app/main/setting.pyINSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main',
]

To connect the django-docker web service to Postgresql db service we need to modify the docker file like below to add the postgresql dependency.

FROM python:3.7.5-buster# set up the psycopg2# First RUN Statement: to install postgresql dependencyRUN apt-get update && apt-get install -y libpq-dev  \
gcc \
postgresql-client
# Second RUN Statement: Install postgresql driver for djangoRUN pip install psycopg2==2.8.3# Third RUN Statement: Remove the gcc compier after install the
# driver
RUN apt-get autoremove -y gcc

After “FROM" statement in Dockerfile. Add those following statement which is provide above.

Explanation of statement:

First RUN instruction, run command to update the repository for base image of docker. then install Postgresql and Postgresql-client and "gcc" as a dependency to set up the psycopg2.

Second RUN instruction installed the psycopg2 PostgreSQL driver library, which will use to connect Django application to PostgreSQL server.

Third RUN instruction, remove gcc dependency, the purpose of the gcc is done completely the building psycopg2 process library.

About env file?

Env file is used for the externalized environment variable to configuration application and docker container. It also helps the developer to easily define the environment variable for application in different purposes to run the application in the docker image also.

Create the env file named postgresql.env in env folder

# django-docker/env/postgresql.envPOSTGRES_USER=hello_django
POSTGRES_PASSWORD=hello_django
POSTGRES_DB=hello_django_dev

Add environment variable related to Postgresql server connection with Django Application to django.env file

# django-docker/env/django.envDEBUG=1
SECRET_KEY=foo
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
# Environment Variable which is used in setting.py in django
# setting.py file to configure the database connection for
# application
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=django_docker
SQL_USER=django_docker
SQL_PASSWORD=django_docker
SQL_HOST=db
SQL_PORT=5432

Reconfigure the settings.py file in django-docker/app/main/settings.py file

Figure: config 1.1

I already discussos.environ library in the first part of my article, this library is used to process the environment variable by python.

What is the docker entry-point shell file?

entry point shell file is created to run the command after the container image in a docker environment. sometimes we need to run command which is related to application configuration, application database migration and application status check, create the scheduler to run the different tasks, all of the instruction we can declare at entry point shell file, add those entry point shell file to “ENTRYPOINT” statement in “Dockerfile”. We can add multiple entry-points sh (shell) files as an array format to the “ENTRYPOINT” statement.

Create the docker-entrypoint.sh file for doing some household work before start django-docker

In-Line 3 to 8, used for Flush any previous unsaved manage.py command at Django application, before starting the django-docker application.

In-Line 12 to 16, command used for migrating any database change before starting the Django application in docker-container

In-Line 20, exec “$@”, is used for taking the other command as an argument after accessing container manually to docker image or container.

Add those line into end of the Dockerfile file

# django-docker/app/Dockerfile# set the docker entry fileRUN chmod +x /opt/app/docker-entrypoint.sh
ENTRYPOINT [ "/opt/app/docker-entrypoint.sh" ]

After modifying the Dockerfile , the final docker file looks like below one

Then add db server to docker-compose.yml file

How web service is working already described in the previous article. you can find it at first part of my article, below, I just discuss how “db” service works with docker-compose

volumes:
postgres_data:
driver: local
--------------------------------------------------------------------
Specify the `postgres_data` volume use the local driver for mount in docker container
--------------------------------------------------------------------

“db” Service section in the docker-compose file.

db:
image: postgres:12.0-alpine
volumes:
- postgres_data:/var/postgres/data/
env_file:
- ./env/postgresql.env
--------------------------------------------------------------------
This difination means, db service use the base image as `postgres:12.0-alpine` image, using the `postgres_data` as volumne to save information and data of the server. using the `./env/postgresql.env` file to load the environment variable for configure the postgresql database.
--------------------------------------------------------------------

About Migration and Migration process in Django with local Environment and In Docker Container

I create the Company model before creating the migration and migrate the model into the database

I inherit the django.db library model class to create the Company model. class. InMeta nested class, we can define different meta information related to the model such as

ordering is used to specifying the array of the field names, which fields you have to use for ordering.

table_name , specify the table name of database you want to use for this model.

def __str__(self):
return self.name

This function is helping to return the name of the object of the model, if we want to log and print the object name to in python code we need this function. for the Django template, if we want to print the name of the object of the model, just specify the object, we need this "__str__" function.

Notes:

For Migration purposes, we need to use the local environment, which I built with pipenv, because if we want to migrate a new model or update some field to web application, some times it creates a new auto migration for building image by running docker-compose up — build command. And the auto migration file is not available in local codebase at the host machine. So, it creates errors in a docker container during building a docker image.

To keep it simple, I reconfigure code at settings.py Figure: Config 1.1, where I specify that, in the local pipenv environment, using sqlite3 as a database for migration. And For the docker environment, using a Postgresql database for migration.

To Create Migration, migration command would like that below

> python manage.py makemigrations [module_name]

I create the model in the main module, so the migration command will be like below

> python manage.py makemigrations main

After Complete the command the folder structure will be like below

django-docker
└──
app
│ ├── main
│ │ ├── migrations
│ │ │ ├── __inti__.py
│ │ │ ├── 0001_initial.py

That command generates automatically in main folder, the migrations folder contains 0001__initial.py migration file, which contains allddl of create command of acompany table in the database for Company model .

Finally, to make migration of a model into the database, using the following command below

> python manage.py migrate

Then run the command to build the application in docker by using docker-compose

> docker-compose up --build

Check the django web service is connected with postgresql web service

Check the django-docker project is connected sqlite3 database in the local environment

Go to the app directory then run the command below

> python manage.py shell

You can now Log in to Interactive shell for Project with Django. Then run the command below

To save the Company into database>>> from main.models import Company
>>> company = Company()
>>> company.name = "New-Company-One"
>>> company.address = "new company address"
>>> company.country = "Japan"
>>> company.city = "Tokyo"
>>> company.save()
To Get Data from database>>> Company.objects.all()
<QuerySet [<Company: New-Company-One>]>
To Exit the interactive shell>>> exit()

Check django-docker a container is connected to postgresql database service from django shell

You have down the docker servers by below command

> docker-compose down> docker-compose up --build -d

Then to run Django interactive shell run the command below from a terminal

> docker-compose exec web /bin/bash

You are now in the shell of the Django docker container

root@<image-no>:/opt/app# python manage.py shell

You can now Log in to Interactive shell for Project with DJANGO. Then run the command below

TO save the Company into database>>> from main.models import Company
>>> company = Company()
>>> company.name = "New-Company-two"
>>> company.address = "new company address two"
>>> company.country = "Bangladesh"
>>> company.city = "Bangladesh"
>>> company.save()
To Get Data from database>>> Company.objects.all()
<QuerySet [<Company: New-Company-two>]>
To Exit the interactive shell>>> exit()

You need to flush the command after a run in the docker container

> python manage.py flush --no-input# Use exit to logout from docker container bash> exit

You can find the whole codebase in GitHub repositor’s “feature/automated-migration” branch

Clone the repository by git

  1. git clone https://github.com/tariqulislam/django-docker.git
  2. Checkout to the branch “git checkout feature/automated-migration

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store