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
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
# driverRUN 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
# applicationSQL_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
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
- git clone https://github.com/tariqulislam/django-docker.git
- Checkout to the branch “git checkout feature/automated-migration”