Dockerize a Django Application

In this article, we will see how to dockerize a Django Python application.
What is the advantage of Dockerizing your Python application?
  • you can run the app without installing Python.
  • no version clash on hosts with a different version of Python installed.
  • no need to install dependencies.
  • no need to remember which is the command to run your Python app.
  • The last one can sound trivial for pure Python developers but think about a big system made by microservices and using 3/4 different languages with different versions.
    We just want to run our application, and probably with different commands for development and production.
    Python
    Accordingly to their own definition, Python is a programming language:
  • high-level
  • interpreted
  • general-purpose
  • Its design emphasizes code readability with its use of significant indentation (no semicolons).
    Its language constructs as well as its object-oriented approach aim to help programmers write clear and logical code.
    Django
    Django is a high-level Python web framework. It’s free and open source.
    Docker
    Docker is a platform to build run and share applications using the idea of containers.
    Step By Step guide
    Prerequisites:
  • Python installed
  • pip installed
  • docker installed
  • Steps:
  • verify prerequisites
  • install django-admin with pip
  • create a Django hello world app
  • run Django app locally (without Docker)
  • create requirements.txt file
  • create the Dockerfile, docker-compose.yml, .dockerignore
  • build and run in just one command
  • verify prerequisites
    python --version
    In some cases, you need to add a 3 at the end of Python:
    verify that pip is installed
    pip --version
    verify that docker is installed
    docker version
    install django-admin with pip
    install django-admin using pip
    pip install django-admin
    create a Django hello world app
    use django-admin to create your Django application, using this command:
    django-admin startproject python_docker
    get into the folder:
    cd python_docker
    and open it using your favorite IDE. For example, if you use Yosual Studio Code, you can type
    code .
    and your project should look like this:
    run Django app locally (without Docker)
    Run your Django project locally without docker using this command:
    python manage.py runserver
    (replace with python3 if you have that version)
    Now visit localhost:8000 on your browser:
    create requirements.txt file
    Before creating the Docker image, let's create a requirements.txt file for this project.
    For simplicity, we will use the command pip freeze and redirect the output to a file called requirements.txt
    pip freeze -l > requirements.txt
    the -l option (short for --local) is to install only the local dependencies.
    Note that the best way to do this is to create a virtual environment first, here is a link
    https://docs.python.org/3/library/venv.html
    Docker
    Let's start the process of containerization for our Python application.
  • create .dockerignore file
  • create Dockerfile
  • create docker-compose.yml file
  • build and run the service with just one command
  • final test
  • .dockerignore
    in the same folder, create a file called .dockerignore (starts with a dot)
    this file, in a way similar to .gitignore, is to ignore some file when we will copy files inside the Docker image. For example, we don't want the .git folder in our image, so we can populate the .dockerignore file with
    .git
    Dockerfile
    now let's create a file called Dockerfile (capital D).
    A Dockerfile is a simple yet powerful text file, with the format:
    KEY value
    KEY value
    KEY value
    Let's populate the Dockerfile like this:
    FROM python:3
    
    ENV PYTHONUNBUFFERED=1
    
    WORKDIR /code
    
    COPY requirements.txt .
    
    RUN pip install -r requirements.txt
    
    COPY . .
    
    EXPOSE 8000
    
    CMD ["python","manage.py","runserver","0.0.0.0:8000"]
    Let's explain line by line what's happening here:
    FROM python:3 FROM is to set the base image, in this case python:3 in a production-ready environment we can use a more fine-grained version
    ENV PYTHONUNBUFFERED=1 We are setting an environment variable with a key=PYTHONUNBUFFERED to 1. Setting PYTHONUNBUFFERED to a non-empty value ensures that the python output is sent straight to the terminal without being first buffered, so you can see the output of your application in real-time.
    WORKDIR /code We are setting the default directory for the subsequent COPY and CMD commands. This line is not mandatory but is to avoid the app being at the root level of the Docker Image filesystem
    COPY requirements.txt . This will copy the requirements.txt file in the folder defined as workdir
    RUN pip install -r requirements.txt This will install the python dependencies INSIDE the Docker Image
    COPY . . This command will copy all the file and folders (included the Dockerfile) in the Image filesystem. al files and folders included in the .dockerignore file will be ignored
    EXPOSE 8000 This command is to inform Docker that you will use the port 8000 as an external note. (Note: this command is not mandatory, as long as you publish the port when you run the container)
    CMD ["python","manage.py","runserver","0.0.0.0:8000"] this will set the default command to run when we will run the container based on this image. this replaces the command we previously used, and it makes transparent for the deployment (you don't have to memorize which was the command to run the python application)
    Docker compose and docker-compose.yml file
    An easy and comfortable way to run our hello world application is to use Docker Compose, even if we have just a small app. In case we add a database or another service later, we are set already!
    Create a docker-compose.yml file and populate it like this:
    version: "3.9"
    
    services:
      django:
        image: django-hello-world:0.0.1
        build: .
        ports:
          - "8000:8000"
    Here we are defining:
  • a single service (container) called "django"
  • the service is based on an image called "django-hello-world:0.0.1". if this image is not available locally, Docker will build it (feel free to rename this image name)
  • build: . mind the dot! this is the path we are using to build our image
  • ports: here we are defining the port we want to publish.
  • That's it. Very simple but it allows us to avoid long docker build command on the command line
    Your folder structure should look like this
    Build and run in just one command
    Now some magic. Just run
    docker compose up --build
    the --build option is to force to recreate the image if it's not available already. It's not really needed the first time, since the image is not available, but it's useful during development to just make some changes and to test if everything works test
    Now visit 127.0.0.1:8000 (ignore the log message it can be deceiving)
    Thank you for reading, you can follow me on Twitter here: https://twitter.com/intent/follow?screen_name=FrancescoCiull4

    25

    This website collects cookies to deliver better user experience

    Dockerize a Django Application