Django 2: Create a containerized Django app with Gunicorn and Docker
Tags: django, python, docker, linux
Published: 2024-02-28 20:12:25

> _NOTE: This article was initially posted on my Substack, at https://andresalvareziglesias.substack.com/_

Hi everyone!

In the first post of this Python/Django/Docker tutorial series, we define an idea to test these technologies with a real application: a supercool version of Tic Tac Toe with magical gems, and dragons, and a supersmart CPU player that uses IA. And sparks. A lot of sparks.

The first stone of our new super cool project is the structure of containers of our project.

Let's get started!

## Articles in this series

- Chapter 1: [Let the journey start](https://andresalvareziglesias.substack.com/p/let-the-journey-start-with-python-docker-and-ai?utm_source=post-toc)
- Chapter 2: [Create a containerized Django app with Gunicorn and Docker](https://andresalvareziglesias.substack.com/p/create-a-containerized-django-app?utm_source=post-toc)
- Chapter 3: [Serve Django static files with NGINX](https://andresalvareziglesias.substack.com/p/serve-django-static-files-with-nginx?utm_source=post-toc)
- Chapter 4: [Adding a database to our stack](https://andresalvareziglesias.substack.com/p/adding-a-database-to-our-stack?utm_source=post-toc)
- Chapter 5: [Applications and sites](https://andresalvareziglesias.substack.com/p/django-5-applications-and-sites)
- Chapter 6: [Using the Django ORM](https://andresalvareziglesias.substack.com/p/django-6-using-the-django-orm)
- Chapter 7: [Users login, logout and register](https://andresalvareziglesias.substack.com/p/django-7-users-login-logout-and-register)

## Create a containerized Django app

We will create a main project folder:

```
mkdir tic-magical-line
cd tic-magical-line
```

And inside, a dedicated folder to our Django app:

```
mkdir app
cd app
```

Once inside the correct folder, we will create a Python virtual environment. This is a very useful way to isolate our projects dependencies from other projects, avoiding the (very frequent) Python libraries conflicts.

It's very easy to create and activate a virtual environment:

```
python3 -m venv .
```

Once created, a virtual environment is activated with this command:

```
source ./bin/activate
```

To deactivate use just:

```
deactivate
```

Now, we can install the Django dependencies and create our app skeleton. Use the Python package manager to install everything we need:

```
python3 -m pip install django
```

After the installation, the Django command line assistant will be available. We will use it to create our project inside a folder named src.

```
mkdir src
cd src
django-admin startproject ticmagicalline
```

The manage.py script is the Django's command-line utility for administrative tasks. It is created in every Django project and allows us to do some useful project management tasks.

The other folder is where our app code resides.

Now, the Django app is created, we can test it with Django embedded web server:

```
python manage.py runserver 0.0.0.0:8080

```
Now, navigate to http://localhost:8080 and voila! Our first application is up and running!

## Pack the Django app inside a Docker container

Now, we will pack this app inside a Docker container. Create three files in the root of our app folder:

```
cd tic-magical-line/app
touch Dockerfile
touch environment.env
touch requirements.txt
```

The environment.env file will contain our environment variables, like debug mode, secret string, etc. Very useful to separate secret variables (like service credentials or tokens) from the source code. For now, its content will be:

```
DEBUG = 1
SECRET_KEY = 'django-insecure-$$$someRandomStringHere$$$'
ALLOWED_HOSTS = ['*']
```

The requirements.txt file contains the dependencies to be installed in the new container. Its content will be:

```
Django
gunicorn
psycopg2-binary
```

As you can see, we define gunicorn as a dependendy, because our application will be server by gunicorn.

The last file, Dockerfile, is the main container definition:

```
FROM python:3.12.2-bookworm

# set some environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY ./src/ticmagicalline .

EXPOSE 8080
CMD ["gunicorn", "ticmagicalline.wsgi:application", "--bind", "0.0.0.0:8080"]
```

The container will install all our dependencies and copy the code of our app. Quick and simple, isn't?

To test now our new container, first we need to build it with this command (we will use the -t argument to tag our build):

```
docker build . -t ticmagicalline:0.1.0
```

When the build ends, we can get the new image ID with:

```
docker images | grep ticmagicalline
```

And then, run the generated image with this image ID (note: will be different in your compilation):

```
docker run -p 8080:8080 fd99e13e2681
```

Navigate again to http://localhost:8080 and voila! Our first containerized application is up and running!

## About the list

Among the Python and Docker posts, I will also write about other related topics (always tech and programming topics, I promise... with the fingers crossed), like:

- Software architecture
- Programming environments
- Linux operating system
- Etc.

If you found some interesting technology, programming language or whatever, please, let me know! I'm always open to learning something new!

## About the author

I'm Andrés, a full-stack software developer based in Palma, on a personal journey to improve my coding skills. I'm also a self-published fantasy writer with four published novels to my name. Feel free to ask me anything!