A preface.

Docker technology is very popular right now, building project environments through containers, running efficiency and deployment efficiency are very good. So I recently took some time to read some tutorials, and then changed the blog deployment mode to Docker. I feel that there is no particularly good tutorial about Docker deploying Django project on the Internet, so I specially wrote this article to record my own experience.

The Deepin test environment will focus on container choreography and Django-related deployments. Some details, such as environment-dependent installation, will not be covered in great detail. Because the test is local, the HTTP proxy is configured instead of the HTTPS proxy when configuring nginx-related information.

Two. Environmental dependence

Docker plus Docker-compose is selected as the deployment mode, so docker and Docker-compose need to be installed.

  • Docker can be installed by sudo apt install docker-ce.

  • Docker-compose can be installed with the following command.

Sudo curl -l https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose- ` ` uname - s - ` uname -m ` > /usr/local/bin/docker-composeCopy the code
sudo chmod +x /usr/local/bin/docker-compose
Copy the code
  • After the installation is complete, enter Docker Version, and the following screen indicates that docker is successfully installed.

  • Enter docker-compose version, and the following screen indicates that docker-compose installation is successful.

Deployment analysis

  • The blog project uses Django, Mysql, Redis, and Nginx, so you need four containers, one for each application. Of course, these containers are sequential, that is, there are dependencies. Then, the four containers are arranged by Docker-compose to build the container running environment.

  • Four containers in total:

    1. Redis container: cache service
    2. Mysql container: Data store
    3. Django (Gunicorn) container: Handles dynamic requests
    4. Nginx container: Reverse proxy that handles static resources
  • The following is a diagram of the container.

  • Container dependencies: Django containers rely on Redis and Mysql containers, and Nginx containers rely on Gunicorn containers.

Iv. Project structure

If you are watching this tutorial, try to keep the directory as the same as the directory in the tutorial. Otherwise, errors may occur during the subsequent deployment.

  • My_blog is the Django project directory, and the Deployment folder holds the three container configuration information in addition to the Django container. Yml: curated container file start.sh: shell command executed after container initialization script requirements. TXT: docker-comemage. yml: curated container file start.sh: shell command executed after container initialization script requirements. TXT: The django project environment depends on the gunicorn.conf: gunicorn configuration file

  • The Deployment directory contains mysql container configuration information, nginx container configuration information and redis container data directory. Mysql: places the database configuration information, conf places the database initialization configuration file my.cnf, data is used to mount the database data, init places the SQL script (import the table structure and data, and mount it to the container). Nginx: places nginx configuration information, SSL places SSL certificates redis: mounts Redis data

Build a Django container environment

1. Django project Dockerfile writing

The container environment and the native environment are isolated. You can think of the container as another system, which is not related to your native system at first. We configure and build the container environment by writing Dockerfile files (just as we would configure python on a clean system).

Set up python3.6
FROM daocloud.io/python:3.6

# Mirror author
MAINTAINER zyk 2295098032@qq.com

Set python environment variables
ENV PYTHONUNBUFFERED 1

# create my_blog folder
RUN mkdir /my_blog

# set my_blog folder as working directory
WORKDIR /my_blog

Add the current directory to the working directory.
ADD . /my_blog

# use PIP install dependencies (-i indicates the specified source, default source download is slow)
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

Set environment variables
ENV SPIDER=/my_blog
Copy the code

2. Write the Gunicorn configuration file

Compile the gunicorn.conf file to start Gunicorn

workers=3 # Number of parallel working processes
threads = 2 # number of threads per worker
bind=['0.0.0.0:8000'] Listen to port 8000 on the Intranet
proc_name='my_blog' # process name
pidfile='/tmp/blog.pid' Set the process file directory
worker_class='gevent' # Work mode coroutine
timeout=30 # timeout
max_requests=6000 # maximum number of requests
Copy the code

3. Write the start.sh command script

The start.sh script is used to start the Django container

#! /bin/bash
#From the first line to the last line, respectively:
#If you don't have the celery, delete the first line
#2. Collect static files to the root directory.
#3. Generate database executable files.
#4. Modify the database according to the database executable file
#5. Start the Django service with Gunicorncelery multi start w1 -A celery_tasks.tasks worker -l info&& python manage.py collectstatic --noinput&& python manage.py  makemigrations&& python manage.py migrate&& gunicorn my_blog.wsgi:application -c gunicorn.confCopy the code

Build an Nginx container environment

1. Nginx container Dockefile preparation

  • Create and write a Dockerfile in the nginx folder
# nginx mirror
FROM daocloud.io/nginx

Delete the existing configuration file and create a static resource folder and SSL certificate save folder
RUNrm /etc/nginx/conf.d/default.conf \ && mkdir -p /usr/share/nginx/html/static \ && mkdir -p /usr/share/nginx/html/media \  && mkdir -p /usr/share/nginx/ssl
Add a configuration file
ADD ./nginx.conf /etc/nginx/conf.d/
Copy the code

2. Configure nginx. Conf

  • Conf is used to reverse proxy the domain name or IP to route dynamic requests to port 8000 of the internal Django container and configure static resource paths.

  • When configuring the reverse proxy, be sure to change host to Web, which is the name of the Django container (configured in docker-comemage.yml).

# Only for local Docker environment testing (port 80 proxy HTTP requests)
server {
    listen 80; # listen on port 80
    server_name  127.0.0.1;  Production environment please change the domain name
    location / {
        proxy_pass http://web:8000; Web is the name of the Django container. Do not write a domain name or IP address
        proxy_set_header Host $host;
        proxy_redirect off;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /static/ {
        alias /usr/share/nginx/html/static/; Static resource path
    }
    location /media/ {
        alias /usr/share/nginx/html/media/; # Upload file path}}Copy the code

7. Configure mysql

1. Write the my.cnf file

The my.cnf file used to initialize the mysql configuration will be mounted into the container.

[mysqld] user=mysql default-storage-engine=INNODB character-set-server=utf8 sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBST ITUTION [client] default-character-set=utf8 [mysql] default-character-set=utf8Copy the code

2. Import the initial SQL file (you can skip this step if you do not need to import the initial database).

Place the SQL file to be imported into the init directory and rename it init.sql

Docker-compose compose container

Write the docker – compose. Yml

version: "3"
services:
  redis:
    image: daocloud.io/redis:3
    command: redis-server
    volumes:
      - ./deployment/redis:/data
    ports:
      - "6379:6379"
    restart: always Always Restart the table container when an error occurs

  db:
    image: Daocloud. IO/mysql: 5.7
    environment:
      - MYSQL_DATABASE=my_blog # database name
      - MYSQL_ROOT_PASSWORD=19960331 # database password
    volumes:
      - ./deployment/mysql/data:/var/lib/mysql # mount database data
      - ./deployment/mysql/conf/my.cnf:/etc/mysql/my.cnf Mount the configuration file
      - ./deployment/mysql/init:/docker-entrypoint-initdb.d/ Mount data to initialize SQL script
    ports:
      - "3306:3306"
    restart: always

  web:
    build: .
    expose:
      - "8000"
    volumes:
      - .:/my_blog
      - /tmp/logs:/tmp
    command: bash start.sh
    links:
      - db
      - redis
    depends_on:
      - db
      - redis
    restart: always

  nginx:
    build: deployment/nginx
    ports:
      - "80:80"
      - "443:443"
    expose:
      - "8000"
    volumes:
      - ./collect_static:/usr/share/nginx/html/static # mount static files
      - ./media:/usr/share/nginx/html/media # Mount upload file
      - ./deployment/nginx/ssl:/usr/share/nginx/ssl # Mount SSL certificate directory
    links:
      - web
    depends_on:
      - web
    restart: always
Copy the code
  • Redis, DB, Web, and nginx are container names.

  • Image represents the image name, and build looks for the Dockerfile in the given directory and builds the container environment.

  • Expose means to expose ports to other containers, but not to hosts (different containers are isolated from each other by default).

  • Ports: maps the container port to the host port (read from right to left, for example, ports: – “3307:3306” maps the container port to the host port 3307). The container port can also be opened to other containers.

  • When volumes are mounted, you can map the local files to the files in the container. The container and the local environment are isolated. Mounting volumes creates a small hole for data communication between the two.

  • Links means to connect containers together.

  • Depends_on: Because containers are started in a sequential order, Django containers rely on mysql containers and Redis containers (Django needs to read and write data from databases and caches), Nginx relies on django containers (nginx containers need to reverse proxy port 8000 of Django containers)

Build and run containers

  • Before you can build the run container, you need to modify the Settings.py file of your Django project.

  • Change database connection HOST to mysql container name db

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql'.# mysql driver
        'NAME': 'my_blog'.# database name
        'USER': 'root'.# Login account
        'PASSWORD': '19960331'.# login password
        'HOST': 'db'.# host address (container deployment)
        # 'HOST': '127.0.0.1', # HOST address
        'PORT': '3306'.# port
        'OPTIONS': {'charset': 'utf8mb4'}}},Copy the code
  • Change host in cache configuration to redis container name redis (if you have redis configured for cache, ignore if not)
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache'.'LOCATION': 'redis://redis:6379'.# redis (container)
        # 'LOCATION' : '127.0.0.1:6379',
        'OPTIONS': {
            "CLIENT_CLASS": "django_redis.client.DefaultClient"."CONNECTION_POOL_KWARGS": {"max_connections": 100},
            'SOCKET_TIMEOUT': 10,,}}}Copy the code
  • In production deployment, change DEBUG = True in settings.py to DEBUG = False to disable the DEBUG mode.

  • Finally, execute docker-compose up –build in the project root directory.

  • After execution, the following screen shows that the build is successful.

  • Access 127.0.0.1 or your public IP address in the browser port. If successful, the build is successful.

Ten. In the end

Docker-compose is the first time for me to deploy a Django project using docker-compose.