Django-Docker Containerized Deployment: Django-Docker-MySQL Deployment

Keywords: Linux MySQL Django Docker Database

In the previous chapter, we successfully built a containerized Django project, using the default Sqlite database. Sqlite is easy to use, but online deployment often chooses more efficient and reliable databases, such as MySQL.

Based on the previous chapter, this chapter will modify and build the container project of Docker + Django + MySQL.

Docker-compose

When we learn the object-oriented programming language, we will try our best to separate the functional independent modules for easy reuse and maintenance.

The same is true of containers. Although it is theoretically possible to plug all components into the same container, it is better to keep the modules in separate containers as long as necessary communication is maintained.

In other words, two containers are now required in this tutorial:

  • Django container named app
  • MySQL container named db

So how to build MySQL mirror? Don't worry, the commonly used mirror authorities have built it for you, just pull it from the warehouse to the local place.

Modify docker-compose.yml written in the previous chapter to add MySQL containers:

version: "3"
services:
  app:
    restart: always
    build: .
    command: bash -c "python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: mysql:5.7
    volumes:
      - "./mysql:/var/lib/mysql"
    ports:
      - "3306:3306"
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=mypassword
      - MYSQL_DATABASE=django_app

The command instruction of the app container has been modified to allow it to perform data migration before running; a new configuration depends_on has been added, meaning that the container needs to wait for the db container to start before it can start.

Analyse the newly added db container:

  • image: Draw MySQL 5.7 from the warehouse. The latest version is MySQL 8, but the pit is that the new version modifies the authentication method of user login, which makes it easy to fail to authenticate. For the sake of simplicity, the 5.7 version is selected. Later meeting Tutorial sample code Add [mysql-8]() branch and give the operation method. Interested readers can see it.
  • Volumes: Define volumes (actually mounted here), as described in the previous chapter, which implements the mapping of host and container directories. The function is to map MySQL data in the container to the host.
  • ports: MySQL default communication port is 3306.
  • Environment: Define the environment variables of the container, set the password of MySQL root user and the name of the database.

Why use rolls here? Is it not good to keep data in containers and isolated? It is theoretically possible to store data in containers, but there is a fatal problem, that is, the life cycle of data and containers is linked: if one day the containers are deleted by the cheap hand, along with the data inside, you will be the legend of the whole company. Know that the life cycle of the container can be very short and that the deletion instructions are fairly docker-compose down. Map the data to the host, and even if the container is deleted, the data is still safe in your server. In other words, the container interior is well suited for running stateless applications; when it comes to stateful things like data, think carefully.

Dockerfile

Next, modify the Dockerfile:

FROM python:3.7
ENV PYTHONUNBUFFERED 1

# Add these two lines
RUN apt-get update
RUN apt-get install python3-dev default-libmysqlclient-dev -y

RUN mkdir /code
WORKDIR /code
RUN pip install pip -U
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

The two additional lines of code install MySQL connector in the system, as explained in detail. Official Documents.

Other configurations

Modify requirements.txt to add MySQL driver:

django==2.2
mysqlclient==1.3.14

Then you need to modify django_app/settings.py to set the database to MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_app',
        'USER': 'root',
        'PASSWORD': 'mypassword',
        'HOST': 'db',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}

Note that HOST fills in the name of the container, db.

That's all right. Next, test.

test

Before testing, make sure that no other program takes up 3306 ports, such as MySQL installed on the host.

Reconstruct the mirror:

$ docker-compose build

Generate and start the container:

$ docker-compose up

Creating network "django_app_default" with the default driver
Creating django_app_db_1 ... done
Creating django_app_app_1 ... done
Attaching to django_app_db_1, django_app_app_1
db_1   | 2019-10-06T12:24:57.183860Z 0 [Note] mysqld (mysqld 5.7.27) starting as process 1 ...

...

db_1   | 2019-10-06T12:24:58.120480Z 0 [Note] mysqld: ready for connections.
db_1   | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

app_1  | Operations to perform:
app_1  |   Apply all migrations: admin, auth, contenttypes, sessions
app_1  | Running migrations:
app_1  |   Applying contenttypes.0001_initial... OK
...
app_1  |   Applying sessions.0001_initial... OK

app_1  | Watching for file changes with StatReloader
app_1  | Performing system checks...
app_1  | 
app_1  | System check identified no issues (0 silenced).
app_1  | October 06, 2019 - 12:24:58
app_1  | Django version 2.2, using settings 'django_app.settings'
app_1  | Starting development server at http://0.0.0.0:8000/
app_1  | Quit the server with CONTROL-C.

Open the browser to visit 127.0.0.1:8000, and you can see the Django rocket.

Note: The first time you start the container, you may have an error that you can't connect MySQL. This is because although the db container has been started, the initialization is not complete; after restarting the container, it will work properly. If multiple startups fail to work properly, that's another reason. Check it carefully.

summary

In this chapter, MySQL containers are added and multi-containers work together.

The next chapter will implement the formally deployed Docker + Django + MySQL + Nginx + Gunicorn project.

Posted by blckspder on Wed, 09 Oct 2019 18:04:02 -0700