Containerising a simple Django application

In this article, we'll take you on a hands-on journey to containerize a Django application from scratch. Whether you're new to Django or Docker, we'll break down everything β from understanding the core structure of a Django project to building your own Docker image and running your app inside a container. Letβs turn your Django project into a portable, production-ready container β step by step!
1) Understanding the basics of a django project :
Install python, django in ur terminal.
And then run the following commands:
django-admin startproject myproject
cd myproject
- This will create myproject folder and the structure of myproject looks like:
π§ STRUCTURE :
myproject/
βββ manage.py
βββ myproject/
β βββ __init__.py
β βββ settings.py
β βββ urls.py
β βββ asgi.py
β βββ wsgi.py
- Now lets explore all components in myproject / myproject folder:
Project Folder: myproject/
This contains global settings for the project.
a. __init__.py
- Makes this folder a Python package.
b. settings.py
Contains project-wide settings:
INSTALLED_APPS
: List of all Django apps.DATABASES
: DB connection info.MIDDLEWARE
: Middleware stack.TEMPLATES
: Template engine config.STATIC_URL
,MEDIA_URL
: For static/media files.
c. urls.py
Main URL configuration file.
You route URLs to views here.
Can include app-level URLs:
path('myapp/', include('myapp.urls'))
d. asgi.py
& wsgi.py
Entry points for deployment:
Now we came to know that myproject / myproject folder is just a settings folder. The actual logic of applications lies in their app folders.
- Now in the
myproject/
folder to create a app folder with the namemyapp/
, run this command:
python manage.py startapp myapp
Now the folder structure will be:
π§ STRUCTURE
myproject/
βββ manage.py
βββ myproject/
β βββ __init__.py
β βββ settings.py
β βββ urls.py
β βββ asgi.py
β βββ wsgi.py
βββ myapp/
β βββ admin.py
β βββ apps.py
β βββ migrations/
β βββ models.py
β βββ tests.py
β βββ views.py
β βββ urls.py
β βββ forms.py (optional)
β βββ templates/
β βββ myapp/
β βββ example.html
myapp/
is the folder containing the actual application logic.
- The general components in any application folder are:
πΉApp Folder: myapp/
This is where your application logic lives.
a. admin.py
- Registers models to Django admin panel.
b. apps.py
- App configuration class.
c. migrations/
Auto-generated DB migration files.
Contains
__init__.py
and numbered migrations like0001_
initial.py
.
d. models.py
Defines database models.
Example:
class Student(models.Model): name = models.CharField(max_length=100)
e. views.py
Handles request and response.
View functions or class-based views:
def home(request): return render(request, 'myapp/home.html')
f. urls.py
(optional but recommended)
App-specific URL patterns.
from django.urls import path from . import views urlpatterns = [ path('', views.home, name='home') ]
πΉ 4. templates/ and static/
- Place these outside the app or inside each app.
a. templates/
HTML files rendered by views.
Follow this structure:
templates/ βββ myapp/ βββ home.html
Use
{% extends "base.html" %}
and{% block content %}
to create reusable templates.
b. static/
For CSS, JS, images, etc.
static/ βββ myapp/ βββ style.css βββ script.js
Add these in settings.py
:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]
β Best Practice Structure:
myproject/
βββ manage.py
βββ myproject/
β βββ settings/
β βββ __init__.py
β βββ base.py
β βββ dev.py
β βββ prod.py
βββ myapp/
β βββ models/
β βββ views/
β βββ urls.py
β βββ forms/
β βββ templates/
β βββ static/
βββ templates/
β βββ base.html
βββ static/
β βββ css/
β βββ js/
β βββ images/
βββ requirements.txt
π§ Summary
Part | Purpose |
manage.py | Entry point for Django commands |
settings.py | All configurations: DB, static, apps, middleware |
urls.py | URL routing |
models.py | Define DB schema |
views.py | Define logic for HTTP requests |
templates/ | Frontend HTML |
static/ | Frontend CSS/JS/Images |
migrations/ | DB schema versioning |
β 1. Real-world projects usually have multiple apps
Example:
Suppose you're building an e-commerce website, you might split features into multiple apps like:
myproject/
βββ users/ # login, registration, profiles
βββ products/ # product listings, details
βββ cart/ # shopping cart
βββ orders/ # order history, payment
βββ reviews/ # product reviews and ratings
βββ myproject/ # main project settings and URLs
βββ manage.py
Each app is a self-contained component responsible for a specific domain of the project.
β 2. How to run all these apps ?
manage.py
remains your central command-line tool even with multiple apps.
When you run:
python manage.py runserver
Django loads all apps listed in
INSTALLED_APPS
(defined insettings.py
).All migrations, views, URLs, models, templates, etc., from each app are registered and active.
Example:
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'users',
'products',
'cart',
'orders',
'reviews',
]
Once listed here, Django manages them together using manage.py
.
β
3. No matter how many apps you have, single manage.py
= All apps run together.
π― Sample Project: myshop
We'll create 3 apps:
users/
β login, register, profileproducts/
β product list/detailorders/
β order history, checkout
ποΈ Folder Structure
myshop/
βββ manage.py
βββ myshop/ # Project settings
β βββ __init__.py
β βββ settings.py
β βββ urls.py # Main URL config
β βββ wsgi.py
βββ users/ # App 1
β βββ admin.py
β βββ apps.py
β βββ models.py
β βββ urls.py # App-specific URLs
β βββ views.py
β βββ templates/users/
βββ products/ # App 2
β βββ admin.py
β βββ apps.py
β βββ models.py
β βββ urls.py
β βββ views.py
β βββ templates/products/
βββ orders/ # App 3
β βββ admin.py
β βββ apps.py
β βββ models.py
β βββ urls.py
β βββ views.py
β βββ templates/orders/
βββ static/
βοΈ Step-by-step Setup
β
1. In settings.py
, add all apps
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
# your custom apps
'users',
'products',
'orders',
]
β
2. myshop/
urls.py
β Main URL router
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls')),
path('products/', include('products.urls')),
path('orders/', include('orders.urls')),
]
β
3. Each app has its own urls.py
π users/
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.login_view, name='login'),
path('register/', views.register_view, name='register'),
]
π products/
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<int:product_id>/', views.product_detail, name='product_detail'),
]
π orders/
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('checkout/', views.checkout_view, name='checkout'),
path('history/', views.order_history, name='order_history'),
]
β 4. Sample Views
products/
views.py
from django.shortcuts import render
def product_list(request):
return render(request, 'products/list.html')
def product_detail(request, product_id):
return render(request, 'products/detail.html')
π How Django maps URLs now:
URL | Mapped to |
/products/ | products.views.product_list() |
/products/5/ | products.views.product_detail() |
/users/login/ | users.views.login_view() |
/orders/checkout/ | orders.views.checkout_view() |
β Key Benefits
Feature | Result |
Modular URL routing | Easy to scale and organize routes |
Per-app templates | Keeps frontend code modular |
Shared settings & run | One manage.py handles all apps |
Clean separation | Easier for teams and maintenance |
As we understood about the folder structure of django, now lets dive into containerisation.
2) Containerising the application :
0) For complete basics on docker, https://github.com/iam-veeramalla/Docker-Zero-to-Hero/blob/main/README.md
i) Installing docker:
sudo apt update
sudo apt install docker.io -y
sudo usermod -aG docker ubuntu
ii) Installing source code and docker file from a github repo:
git clone https://github.com/iam-veeramalla/Docker-Zero-to-Hero.git
cd Docker-Zero-to-Hero/examples/python-web-app
ls
We can see Dockerfile, source code folder and requirements.txt file
iii) With the dockerfile, build an image with docker build .
command.
iv) With docker images
command, u can see our newly created image with its id, size.
v) Now run the container with docker run -p 8000:8000 -it <image-id>
We can see that the container is running.
Subscribe to my newsletter
Read articles from Rajesh Gurajala directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
