If you’re working on a Django project and you want to make your life easier – especially when it comes to running your app across different environments – Docker is your new best friend.
Docker makes it possible to package your Django app, along with all its dependencies, into something called a “container.”
That way, it runs the same on your computer, your teammate’s computer, a testing server, or even in production.
When I first started using Docker, it felt a little overwhelming. But after setting it up for a few Django apps, it all clicked.
The good news? I’m going to walk you through it, step by step, in a way that’s easy to follow, even if you’re brand new to Docker.
Table of Contents
What You’ll Need
Before we begin, make sure you’ve got a few things installed:
Python 3 (any version that Django supports)
Django (of course)
Docker and Docker Compose
👉 Install Docker
👉 Install Docker Compose
You don’t need to be an expert in Docker. I’ll explain what each part does as we build it together.
How to Dockerize Your Django Project
Step 1: Start a Django Project
If you already have a Django project, you can skip this part.
Otherwise, open your terminal and run:
django-admin startproject myproject
<span class="hljs-built_in">cd</span> myproject
This will create a new Django project called myproject
. You’ll see a structure like this:
myproject/
├── manage.py
└── myproject/
<span class="hljs-code"> ├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py</span>
Let’s say this is your app that you want to run inside Docker.
Step 2: Create a Dockerfile
In the root of your project (same folder as manage.py
), create a file called Dockerfile
. No file extension –just Dockerfile
.
Here’s what goes inside:
<span class="hljs-comment"># Use the official Python image</span>
<span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.10</span>-slim
<span class="hljs-comment"># Set environment variables</span>
<span class="hljs-keyword">ENV</span> PYTHONDONTWRITEBYTECODE=<span class="hljs-number">1</span>
<span class="hljs-keyword">ENV</span> PYTHONUNBUFFERED=<span class="hljs-number">1</span>
<span class="hljs-comment"># Set the working directory in the container</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>
<span class="hljs-comment"># Install dependencies</span>
<span class="hljs-keyword">COPY</span><span class="bash"> requirements.txt /app/</span>
<span class="hljs-keyword">RUN</span><span class="bash"> pip install --upgrade pip && pip install -r requirements.txt</span>
<span class="hljs-comment"># Copy the rest of the code</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . /app/</span>
Let me break that down:
FROM python:3.10-slim
: This tells Docker to use a lightweight version of Python 3.10.ENV
: These just help with cleaner logs and better performance.WORKDIR /app
: This sets the default working directory inside the container.COPY
andRUN
: These lines copy your code into the container and install your Python packages.
Step 3: Add a requirements.txt
You’ll need a file listing your Python packages.
Create a file called requirements.txt
in the root folder and add:
Django>=4.0,<5.0
You can add more later if your project grows. For now, that’s enough.
To generate a full list of dependencies from your local virtual environment, run:
pip freeze > requirements.txt
Step 4: Create docker-compose.yml
Now let’s create the file that tells Docker how to run everything together.
In your root folder, create docker-compose.yml
:
<span class="hljs-attr">version:</span> <span class="hljs-string">'3.9'</span>
<span class="hljs-attr">services:</span>
<span class="hljs-attr">web:</span>
<span class="hljs-attr">build:</span> <span class="hljs-string">.</span>
<span class="hljs-attr">command:</span> <span class="hljs-string">python</span> <span class="hljs-string">manage.py</span> <span class="hljs-string">runserver</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:8000</span>
<span class="hljs-attr">volumes:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">.:/app</span>
<span class="hljs-attr">ports:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">"8000:8000"</span>
Let’s go line-by-line:
build: .
: This tells Docker to use theDockerfile
in the current folder.command
: This runs Django’s development server inside the container.volumes
: This mounts your code into the container so changes are reflected live.ports
: This maps port 8000 inside Docker to port 8000 on your machine.
So if you go to http://localhost:8000
, you’ll see your app.
Step 5: Run It!
Now the fun part. From your terminal, run:
docker-compose up --build
This tells Docker to:
Build the container
Install dependencies
Run the Django server
If everything goes well, you’ll see logs from the Django server, and you can open your browser and go to http://localhost:8000
.
You should see the Django welcome screen.
Common Issues
Port Already in Use?
If port 8000 is busy, change this line in docker-compose.yml
:
<span class="hljs-attr">ports:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">"8001:8000"</span>
Then go to http://localhost:8001
.
Database Not Working?
If you need a database (like PostgreSQL), you can add another service to docker-compose.yml
. Here’s an example with PostgreSQL:
<span class="hljs-attr">services:</span>
<span class="hljs-attr">db:</span>
<span class="hljs-attr">image:</span> <span class="hljs-string">postgres</span>
<span class="hljs-attr">environment:</span>
<span class="hljs-attr">POSTGRES_DB:</span> <span class="hljs-string">mydb</span>
<span class="hljs-attr">POSTGRES_USER:</span> <span class="hljs-string">user</span>
<span class="hljs-attr">POSTGRES_PASSWORD:</span> <span class="hljs-string">password</span>
<span class="hljs-attr">web:</span>
<span class="hljs-attr">build:</span> <span class="hljs-string">.</span>
<span class="hljs-attr">command:</span> <span class="hljs-string">python</span> <span class="hljs-string">manage.py</span> <span class="hljs-string">runserver</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:8000</span>
<span class="hljs-attr">volumes:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">.:/app</span>
<span class="hljs-attr">ports:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">"8000:8000"</span>
<span class="hljs-attr">depends_on:</span>
<span class="hljs-bullet">-</span> <span class="hljs-string">db</span>
Then, update your settings.py
in Django to use that database.
FAQs
Do I need Docker for development?
No, but it helps keep your environment clean and consistent. If it works in Docker, it’ll work anywhere.
Can I run migrations inside Docker?
Yes! Just run:
docker-compose run web python manage.py migrate
How do I stop everything?
Press Ctrl+C
to stop the running server, and if you want to remove containers:
docker-compose down
Extra Tip: Use .dockerignore
Just like .gitignore
, you can create a .dockerignore
file to avoid copying unnecessary files into the Docker container. Here’s a simple one:
<span class="hljs-attribute">__pycache__</span>
<span class="hljs-regexp">*.pyc</span>
<span class="hljs-regexp">*.pyo</span>
<span class="hljs-regexp">*.pyd</span>
.env
.git
What You’ve Built
By now, you’ve:
Created a Django project
Built a Docker container for it
Set up
docker-compose
to run everythingLearned how to manage it all easily
Once you’re comfortable, you can expand this setup with static files, NGINX, Gunicorn, or even production-ready Docker builds.
Want to Go Deeper?
If this feels like a lot, that’s ok. It takes a little practice, but once you’ve done it a few times, Docker becomes second nature.
You’ll spend less time debugging setup issues and more time coding your app.
Further Reading
Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & MoreÂ