[PYTHON] How to run a Django application on a Docker container (development and production environment)

Article summary

There are several ways to run a WEB application created with ** Django ** in a ** development / production environment **. Recently, ** Kubernetes ** has become popular and there are many occasions when applications are containerized.

This article describes how to create a ** Docker container ** with a ** Django application ** in a ** development / production environment **.

Prerequisites / Environment

The environment used in this article is ** CentOS7 **, ** Docker **, ** Django2 series **.

As long as ** Docker ** works, ** Docker container ** works, so there is no problem even if the OS is Windows.

Create Docker container for development environment

Docker file to use

The Docker file used for the development environment is as follows.

This Docker file is based on ** debian: 10 ** and has ** Python ** installed from source code. There is also a ** official Python ** Docker image, so it's okay to use it, but it's configured like this for study.

FROM debian:10

# Install Python3.7.7

WORKDIR /work
ADD ./Python-3.7.7.tar.xz .
WORKDIR Python-3.7.7
RUN apt-get update && apt-get install -y \
    gcc \
    libbz2-dev \
    libssl-dev \
    libffi-dev \
    libsqlite3-dev \
    make \
    tk-dev \
    zlib1g-dev \
    apache2-dev \
    python3-dev \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*
RUN ./configure --enable-shared && \
    make && \
    make install && \
    make distclean && \
    ./configure && \
    make && \
    make altbininstall

# Install with pip

COPY ./requirements.txt .
RUN pip3 install --upgrade pip setuptools
RUN pip3 install --upgrade wheel
RUN pip3 install -r requirements.txt

# Deploy App

WORKDIR /
ADD ./deployfiles.tar.xz .
WORKDIR /myapp

CMD ["python3", "manage.py", "runserver", "0.0.0.0:80"]

Docker file description

FROM debian:10

First, when writing a ** Docker ** file, specify what to use as a ** base **. Here, ** debian: 10 ** is specified.

FROM

# Install Python3.7.7

WORKDIR /work
ADD ./Python-3.7.7.tar.xz .
WORKDIR Python-3.7.7

Next is the installation of ** Python **.

** [WORKDIR] 7 ** is a syntax that moves the current directory of the OS. If ** WORKDIR / work ** is specified, a directory called ** work ** will be created directly under the root directory (/) ** (** it will be created if there is no specified directory **), and that is the current. It will be a directory.

** ADD ** can be ** copied / expanded ** to the path on the Docker container by setting the path on the ADD host OS to the path ** on the Docker container. I can do it. ** Unlike [ADD is COPY] 5 **, you can ** decompress compressed files **. Therefore, files such as ** tar ** and ** xz ** should be copied onto ** Docker container ** using ** ADD **.

RUN apt-get update && apt-get install -y \
    gcc \
    libbz2-dev \
    libssl-dev \
    libffi-dev \
    libsqlite3-dev \
    make \
    tk-dev \
    zlib1g-dev \
    apache2-dev \
    python3-dev \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

** [RUN] 3 ** can execute commands on the Docker container. I'm using apt-get to install the dependent packages needed to install ** Python **.

** apt-get clean **, ** rm -rf / var / lib / apt / lists / \ *** are running to remove unnecessary caches and files. By removing this, you can keep the ** capacity of the created ** Docker image ** small **.

RUN ./configure --enable-shared && \
    make && \
    make install && \
    make distclean && \
    ./configure && \
    make && \
    make altbininstall

The rest are **. / Configure **, ** make **, ** make install **. There are about 4 extra lines, but I've added them to handle errors.

*** I think it's a combination problem **, but when I ran it I had to do this. Maybe it's unnecessary.

# Install with pip

COPY ./requirements.txt .
RUN pip3 install --upgrade pip setuptools
RUN pip3 install --upgrade wheel
RUN pip3 install -r requirements.txt

After installing ** Python **, install the ** Python ** package. Here, use the ** pip ** command to install the packages listed in ** requirements.txt **.

** [COPY is similar to ADD] 5 **, ** COPY Path on host OS Path on Docker container ** Copy files on host OS to path on Docker container I can do it. This is literally just a copy.

After that, upgrade ** pip ** with ** [RUN] 3 ** and install the ** Python ** package based on ** requirements.txt **.

# Deploy App

WORKDIR /
ADD ./deployfiles.tar.xz .
WORKDIR /myapp

CMD ["python3", "manage.py", "runserver", "0.0.0.0:80"]

Finally, add your application ** to the Docker container **.

** deployfiles.tar.xz ** is a compressed directory called ** myapp **, with ** manage.py ** directly under ** myapp **.

** [CMD] 4 ** is the syntax to set the command to be executed when the ** Docker container ** starts. This can be described like a list format of ** Python **, and each element is joined with a single-byte space. In other words, the command looks like this:

CMD ["python3", "manage.py", "runserver", "0.0.0.0:80"]
↓
python3 manage.py runserver 0.0.0.0:80

Build Docker image

To build the ** Docker image **, run the following command.

docker build -t test/myapp .

The ** -t ** option is used to tag ** Docker images **. Tagging makes it easier to manage.

At the end of the command, put the path of the ** Docker file **. Here, ** current directory (.) ** is specified.

By default, the file named ** Dockerfile ** is searched from the specified path, so the file name created above is set to ** Dockerfile **.

docker build

To check the created image, execute the following command.

docker image ls

Start Docker container

To start the ** Docker container ** from the ** Docker image **, run the following command.

docker run --name myapp -d -p 80:80 -v /work/db.sqlite3:/myapp/db.sqlite3 test/myapp:latest

The ** --name ** option names the ** Docker container **. This is useful later if you want to stop, start or delete this ** Docker container **. The name will be unique, so if you give it a name, you can stop, start, or delete it just by specifying the name. If there is no name, specify the container ID.

The ** -d ** option runs the container in ** background **. If you don't add this, the standard output of ** Docker container ** will be displayed on the console. You can exit with ** Ctrl + c **. In most cases, I think it will run in the background, so I'll add it.

The **-p ** option associates the ** host OS port ** with the ** Docker container port **. ** Host OS port: Docker container port **. This time, we're publishing the ** Django ** process using ** port 80 ** of the Docker container, so specify 80.

The ** -v ** option associates the ** host OS volume (Docker volume or file path on the host OS) ** with the ** Docker container file path **. The container does not hold any data when it exits. Therefore, the data you want to keep must be stored externally. ** Recommended is Docker volume **, but because of the development environment ** Save data to the file path of the OS on the host **. Here, ** db.sqlite3 ** is linked from ** host OS ** to ** Docker container **.

** test / myapp ** is the specification of the underlying ** Docker image **. ** latest ** is the version name and will be ** latest ** if you don't specify anything when you build the ** Docker image **. You can check it by referring to the ** TAG ** column output by ** docker image ls **.

docker run

To check if it has started normally, execute the following command.

docker ps

If the ** STATUS ** column is ** UP **, it has started normally.

If nothing is output, add ** -a ** to check the stopped process. If you want to check the log of ** Docker container **, execute the following command.

docker logs [Container name or container ID]

Check the error and take corrective action.

Connect to Django applications

Access the public port number of the IP address on the ** host OS ** running ** Docker **.

Create Docker container for production environment

Docker file to use

The ** Docker file ** used for the production environment is as follows.

Unlike the development environment, you cannot start a process with ** python3 manage.py runserver **. It is more stable to run on ** Apache ** etc.

I'm using ** httpd: 2.4 ** as the base here. [** Official Docker image ** of Apache Web Server **] 1.

In order to run ** Django ** on ** Apache **, you need to include a module called ** [mod_wsgi] 2 ** in ** Apache **. Therefore, ** Python ** and ** [mod_wsgi] 2 ** are installed.

FROM httpd:2.4

# Install Python3.7.7

WORKDIR /work
ADD ./Python-3.7.7.tar.xz .
WORKDIR Python-3.7.7
RUN apt-get update && apt-get install -y \
    gcc \
    libbz2-dev \
    libssl-dev \
    libffi-dev \
    libsqlite3-dev \
    make \
    tk-dev \
    zlib1g-dev \
    apache2-dev \
    python3-dev \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*
RUN ./configure --enable-shared && \
    make && \
    make install && \
    make distclean && \
    ./configure && \
    make && \
    make altbininstall

# Install with pip

COPY ./requirements.txt .
RUN pip3 install --upgrade pip setuptools
RUN pip3 install --upgrade wheel
RUN pip3 install -r requirements.txt

# install ModWsgi

WORKDIR /work
ADD ./mod_wsgi-4.7.1.tar.gz .
WORKDIR mod_wsgi-4.7.1
RUN ./configure \
    --with-apxs=/usr/local/apache2/bin/apxs \
    --with-python=/usr/local/bin/python3.7 && \
    make && \
    make install 

# Set Apache

WORKDIR /usr/local/apache2/conf
COPY ./httpd.conf .
COPY ./server.crt .
COPY ./server.key .
COPY ./wsgi.conf ./extra
COPY ./httpd-ssl.conf ./extra

Docker file description

FROM httpd:2.4

** [httpd: 2.4] 1 ** is specified as the base.

# Install Python3.7.7

WORKDIR /work
ADD ./Python-3.7.7.tar.xz .
WORKDIR Python-3.7.7
RUN apt-get update && apt-get install -y \
    gcc \
    libbz2-dev \
    libssl-dev \
    libffi-dev \
    libsqlite3-dev \
    make \
    tk-dev \
    zlib1g-dev \
    apache2-dev \
    python3-dev \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*
RUN ./configure --enable-shared && \
    make && \
    make install && \
    make distclean && \
    ./configure && \
    make && \
    make altbininstall

Install ** Python ** as you would in the development environment.

# Install with pip

COPY ./requirements.txt .
RUN pip3 install --upgrade pip setuptools
RUN pip3 install --upgrade wheel
RUN pip3 install -r requirements.txt

Install the ** Python ** package based on ** requirements.txt ** with ** pip ** as in the development environment.

# install ModWsgi

WORKDIR /work
ADD ./mod_wsgi-4.7.1.tar.gz .
WORKDIR mod_wsgi-4.7.1
RUN ./configure \
    --with-apxs=/usr/local/apache2/bin/apxs \
    --with-python=/usr/local/bin/python3.7 && \
    make && \
    make install 

Install ** [mod_wsgi] 2 ** to get ** Django ** working on ** Apache **.

# Set Apache

WORKDIR /usr/local/apache2/conf
COPY ./httpd.conf .
COPY ./server.crt .
COPY ./server.key .
COPY ./wsgi.conf ./extra
COPY ./httpd-ssl.conf ./extra

Finally, copy the ** Apache ** various ** config ** files and ** certificate related ** files.

Build Docker image

Similar to the development environment.

Creating a Docker volume

To create ** [Docker Volume] 10 **, execute the following command.

docker volume create --name volume-name

** [Docker Volume] 10 ** is created with the name specified by **-name **. This volume is associated with ** Docker container **.

** [Docker Volume] 10 ** has a different lifespan than ** Docker Container **. Even if the ** Docker container ** disappears, ** [Docker volume] 10 ** will continue to exist, so data can be persisted.

Start Docker container

To start the ** Docker container ** from the ** Docker image **, run the following command.

docker run --name myapp -d -p 443:443 -v volume-name:/myapp test/myapp

Only the ** -v ** option is different from the development environment. Here, ** [Docker volume] 10 ** is specified instead of ** file path ** on the host OS. ** [Docker volume] 10 ** named ** volume-name ** is associated with ** / myapp ** on ** Docker container **. This will save the data on ** / myapp ** to ** [Docker Volume] 10 **.

Connect to Django applications

Similar to the development environment.

Source file used

Python

mod wsgi

Recommended Posts

How to run a Django application on a Docker container (development and production environment)
How to use Docker to containerize your application and how to use Docker Compose to run your application in a development environment
How to build a Django (python) environment on docker
How to deploy a Django application on Alibaba Cloud
How to run Django on IIS on a Windows server
Flutter in Docker-How to build and use a Flutter development environment inside a Docker container
Run Matplotlib on a Docker container
[Django] Use VS Code + Remote Containers to quickly build a Django container (Docker) development environment.
Run matplotlib on a Windows Docker container
Learn how to use Docker through building a Django + MySQL environment
[DynamoDB] [Docker] Build a development environment for DynamoDB and Django with docker-compose
How to make a container name a subdomain and make it accessible in Docker
[Python] Build a Django development environment with Docker
[Note] How to create a Ruby development environment
[Note] How to create a Mac development environment
Build a Django development environment using pyenv-virtualenv on Mac
Launch Django on a Docker container with docker-compose up
Build a development environment with Poetry Django Docker Pycharm
How to build a Python environment on amazon linux 2
How to build a beautiful Python environment on a new Mac and install Jupter Notebook
How to create a Python 3.6.0 environment by putting pyenv on Amazon Linux and Ubuntu
A memo on how to easily prepare a Linux exercise environment
How to run a trained transformer model locally on CloudTPU
Build a Django development environment with Docker! (Docker-compose / Django / postgreSQL / nginx)
How to build a new python virtual environment on Ubuntu
[Memo] Build a development environment for Django + Nuxt.js with Docker
Don't lose to Ruby! How to run Python (Django) on Heroku
Create a VS Code + Docker development environment on a Linux VM
A note on how to load a virtual environment in PyCharm
How to build a python2.7 series development environment with Vagrant
How to set up WSL2 on Windows 10 and create a study environment for Linux commands
Put Jupyter and Docker Compose on your Chromebook and use it as a light development environment!
Deploy a Django application with Docker
How to run matplotlib on heroku
How to build a LAMP environment using Vagrant and VirtulBox Note
How to run Jupyter and Spark on Mac with minimal settings
How to build a Python environment using Virtualenv on Ubuntu 18.04 LTS
How to deploy a Django app on heroku in just 5 minutes
How to deploy a web application on Alibaba Cloud as a freelancer
I made a development environment for Django 3.0 with Docker, Docker-compose, Poetry
Launched a web application on AWS with django and changed jobs
Create a simple Python development environment with VS Code and Docker
Building an environment to run ChainerMN on a GPU instance on AWS
Learning history to participate in team application development with Python ~ Build Docker / Django / Nginx / MariaDB environment ~
How to split and save a DataFrame
How to debug a Python program by remotely connecting to a Docker container in WSL2 environment with VS Code
Django development using virtualenv Procedures from virtual environment construction to new project / new application creation and initial settings
Run a Python file inside a Docker container on a remote Raspbian via PyCharm
How to create an NVIDIA Docker environment
How to make a process thread run only on a specific CPU core
Build your Django app on Docker and deploy it to AWS Fargate
How to use tensorflow under docker environment
Run a Python web application with Docker
How to test on a Django-authenticated page
How to run Cython on OSX Memo
Build Linux on a Windows environment. Steps to install Laradock and migrate
How to run a Maya Python script
How to count the number of elements in Django and output to a template
Create a Django project and application in a Python virtual environment and start the server
How to run GUI programs such as tkinter in Python environment on WSL2
How to install Fast.ai on Alibaba Cloud GPU and run it on Jupyter notebook