Introduction
This is a tutorial to show how we can build a Django Rest Project and Dockerize it in Docker container. Here I will be building a Django project first and then dockerize it to a container... This is the good practice who is new to Django and docker.
Prerequisite:
- Python version 3+
- Pip
- PyCharm (or any other IDE support Python)
Create Django Project
Here I'm working on Linux OS, which already comes with Python pre-installed. If Window OS need to install python, recommended to install from windows store.
Steps:
Create a folder. (eg: blog) Open the created folder (blog) in PyCharm IDE. Open Terminal window from bottom of the Application or click Alt+F12 (shortcut).
In the Terminal type:
virtualenv venv
A folder named "venv" will be installed and following some python packages will be installed in the folder. Here we installed the virtual environment for the project. Note: virtual environment is created for temporary purpose only, while dockerizing the project, we won't be needing it anymore.
Let's Activate the Environment by executing the command: . venv/bin/activate
By this time, we can see (venv) is appended in the cursor. It's is a way to identifying that its current environment.
Now lets create a file requirements.txt file. Its a standard procedure to list the required packages to run the project. List of Packages required:
Django==4.1.1
djangorestframework==3.13.1
django-cors-headers==3.13.0
After Copied to the packages to requirements file, Run the command: pip install -r requirements.txt
The Package will be installed in the Environment.
Now Let's create the Project by running the command: django-admin startproject blogpost
The Project will be created and to create an app in the project:
cd blogpost
python manage.py startapp blogapp
By this Stage, the Project and app is created, Some extra tweak is required to run the project: In the settings.py file ( file used to configure the project) add:
"rest_framework",
"blogapp",
in Intalled app list eg:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"blogapp",
]
"rest_framework" is a build-in app in order to use for rest APIs "blogapp" is the app just created, where we are going to build the APIs.
Now in the urls.py file ( file used to list the urls)
add:
from django.urls import path, include
for the import and
path('', include('blogapp.urls'))
in the urlpatterns list
eg:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path(''", include('blogapp.urls'))
]
here we including the app blogapp's urls to the project url list. So in the blogapp folder, we need to create a file urls.py and add:
from django.urls import path
from . import views as blogview
urlpatterns = [
path('', blogview.HomeView.as_view(), name='home')
]
We are using Class based view, which is industry standard as in order to represent as_view() is used. Now lets just simply create a function in views.py file
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
class HomeView(APIView):
def get(self, request):
return Response("hello")
The Project setup is completed. Run Command:
python manage.py migrate
python manage.py runserver
to run the project and project will start and http://127.0.0.1:8000 will be available.
Dockerizing the Project
Now that the Project is ready, We can now dockerize the project.
Prerequisite:
- Docker
- docker-compose
For Linux OS:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
For Windows OS refer:
https://docs.docker.com/desktop/install/windows-install/
Steps:
Completing the installation, create a file docker-compose.yml in the "blog" folder and paste the content:
version: '3.8'
services:
web:
build: ./app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./app/:/usr/src/app/
stdin_open: true
tty: true
ports:
- 8000:8000
env_file:
- ./.env.dev
depends_on:
- db
db:
image: postgres:14.4-alpine
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=password
- POSTGRES_DB=blog
ports:
- 6200:5432
volumes:
postgres-data:
then create a file "Dockerfile" with no extension and "entrypoint.sh" in the folder where manage.py file exists. Paste the content in Dockerfile:
# pull official base image
FROM python:3.8.5-alpine
# set work directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install psycopg2 dependencies
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev libffi-dev
# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
RUN apk --no-cache add \
icu-dev \
gettext \
gettext-dev
## copy entrypoint.sh
COPY ./entrypoint.sh .
RUN sed -i 's/\r$//g' /usr/src/app/entrypoint.sh
RUN chmod +x /usr/src/app/entrypoint.sh
# copy project
COPY . .
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
Paste the content in entrypoint.sh:
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
mkdir -p logs
exec "$@"
Note: Here we are creating container for Postgre DB which is not configure in the project, which is optional
The Docker is ready to Build by the command:
docker-compose up --build
The build will start and server will be hosted on url: http://0.0.0.0:8000/