In the previous chapter, we successfully set up a containerized Django project using the default Sqlite database. Sqlite is simple and easy to use, but is often deployed online with a more efficient and reliable database, such as MySQL.

This chapter will modify and build Docker + Django + MySQL container project on the basis of the previous chapter.

Docker-compose

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

Same thing with containers. Although it is theoretically possible to cram all components into the same container, it is better to keep each module in a separate container, as long as the necessary communication is maintained.

That is, we now need two containers for this tutorial:

  • A Django container named App
  • MySQL container named DB

So how do you build a MySQL image? Don’t worry, such a common image has been officially built for you, just need to pull it from the warehouse to the local can be.

Docker-comemage. yml (docker-comemage. yml)

version: "3" services: app: restart: always build: . command: 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_appCopy the code

The app container’s command has been modified to perform data migration before running; A configuration depends_on has been added, meaning that the container can start only after the DB container has been started.

Analyze the newly added DB container:

  • image: Pull MySQL 5.7 from the repository. The latest version of MySQL is 8, but the new version has changed the authentication method for user login, which makes it very easy to fail authentication. The tutorial uses version 5.7 for simplicity. In the lateTutorial Sample codeaddmysql-8Branch and give the operation method, interested readers can view.
  • volumes: Define volume (actually mount), as described in the previous chapter, which implements the mapping between host and container directories. It maps MySQL data from the container to the host.
  • ports: The default communication port of MySQL is 3306.
  • environment: Defines environment variables of the container, and sets the password of the root user of MySQL and the name of the database.

Why do we use a roll here? Isn’t it good to keep the data in containers, isolated? Storing data in containers is theoretically possible, but there is a fatal problem: the data is tied to the life cycle of the container: if you delete the container and the data is gone with the wind, you will be the legend of the entire company. Keep in mind that the container life cycle can be very short and the delete instructions are docker-compose down. By mapping data to the host, the data remains safe on your server even after the container is deleted. In other words, the inside of a container is perfect for running stateless applications; Think carefully when it comes to stateful things like data.

Dockerfile

Next modify Dockerfile:

FROM Python :3.7 ENV PYTHONUNBUFFERED 1
#Add these two rows
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/
Copy the code

The additional two lines of code install the MySQL connector in the system, as explained in the official documentation.

Other configuration

Add MySQL driver to requirements. TXT

django==2.2
mysqlclient==1.314.
Copy the code

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'}}},Copy the code

Note that HOST is the container name, that is, db.

That will do. Next test.

test

Before testing, make sure that no other programs occupy port 3306, such as MySQL installed on the host.

Regenerating the image:

$ docker-compose build
Copy the code

Build and start the container:

$ docker-compose upCreating 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-06 T12:24:57. 183860 z 0 [Note] mysqld (mysqld 5.7.27) starting as process 1... . Db_1 | 2019-10-06 T12:24:58. 120480 z 0 [Note] mysqld: ready for connections. Db_1 | Version: '5.7.27 sockets: '/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.Copy the code

Open your browser to 127.0.0.1:8000 and you’ll see Django rocket again.

MySQL cannot connect to MySQL when the container is started for the first time. This is because the db container has been started but initialization is not complete. After you restart the container, it works. If multiple starts do not work properly, that is another reason, a good check.

conclusion

In this chapter, MySQL container is added and multiple containers work together.

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


  • If you have any questions please leave a message on Doucet’s personal website and I will reply as soon as possible.
  • Django-docker-tutorial
  • Or Email me a private message: [email protected]