Используйте докер для развертывания проекта стека технологий django

Django
Используйте докер для развертывания проекта стека технологий django

Эта статья была впервые опубликована в техническом блоге DeanWu:Мой друг Ли Сюэмин, Цао Цао/posts/2019-…

Исходная сеть карты заголовков.

Благодаря популярности и зрелости Docker он постепенно стал первым выбором для развертывания проектов.Сегодня я поделюсь с вами тем, как использовать Docker для развертывания проектов стека технологий django.

Стек технологий Django, о котором мы здесь говорим, это: python3.6, Django2.2, redis, mysql, celery, gunicorn и nginx. В реальных производственных проектах эти компоненты распределяются по разным машинам в кластере, например Nginx, Redis и Mysql, за которые могут отвечать отдельные команды или отделы. Архитектура развертывания и задействованная оркестровка контейнеров будут более сложными, и в этой статье мы пока не будем в них углубляться. Эта статья в основном знакомит с тем, как использоватьdocker-composeчтобы организовать эти компоненты, этот способ подходит для развертывания тестовой среды или вашего личногоsideprojectразвертывание.

В этой статье по умолчанию используется то, что вы уже знаетеdockerа такжеdocker-composeНекоторые базовые знания о , если вы не понимаете, вы можете прочитать следующую информацию:

Поговорим о том, как развернуть.

Организационная структура проекта

Во-первых, давайте взглянем на нашу организационную структуру проекта, структура выглядит следующим образом:

├── LICENSE
├── README.md
├── compose
│   ├── celery
│   │   ├── Dockerfile
│   │   ├── celery-beat.sh
│   │   └── celery.sh
│   ├── mysql
│   │   └── my.cnf
│   ├── nginx
│   │   └── nginx.conf
│   └── web
│       ├── Dockerfile
│       ├── entrypoint.sh
│       ├── gunicorn.conf
│       └── gunicorn.sh
├── docker-compose.yml
├── docker_django_demo
│   ├── __init__.py
│   ├── celery.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── env.tpl
├── manage.py
├── requirements.txt

Помимо файлов проекта Django, основные дополненияcomposeкаталог файла конфигурации иdocker-compose.ymlконфигурационный файл.

  • composeВ каталоге в основном хранятся файлы dockerfile и сценарии запуска каждого компонента.
  • docker-compose.ymlЭто файл конфигурации оркестровки docker-compose.

Напишите Dockerfile и запустите скрипт инициализации

В docker-compose есть два способа запустить контейнер: один — напрямую использовать общедоступный образ для запуска контейнера, а другой — использовать Dockerfile, написанный нами. Поскольку нам необходимо установить дополнительные наборы инструментов и инициализировать соответствующую конфигурацию, мы используем настраиваемый файл Dockerfile для веб-компонентов и компонентов celery.

веб-контейнерcompose/web/Dockerfile:

FROM python:3.6
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY ./requirements.txt /code/
RUN pip install --no-cache-dir -r requirements.txt \
    && rm -rf requirements.txt

COPY . /code/
COPY ./compose/web/*.sh /code/
RUN sed -i 's/\r//' gunicorn.sh \
    && chmod +x gunicorn.sh \
    && sed -i 's/\r//' entrypoint.sh \
    && chmod +x entrypoint.sh

ENTRYPOINT ["/bin/bash", "entrypoint.sh"]

Другие файлы для веб-контейнера:

  • compose/web/entrypoint.shСценарий запуска веб-контейнера, который выполняет некоторую логику инициализации или обнаружения.
  • compose/web/gunicorn.confконфигурационный файл пушкикорна.
  • compose/web/gunicorn.shСкрипт запуска для gunicorn.

Докерфайл для сельдерея:

FROM python:3.6
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code

COPY ./requirements.txt /code/
COPY ./compose/celery/*.sh /code/
RUN pip install --no-cache-dir -r requirements.txt \
    && rm -rf requirements.txt && sh init_env.sh

COPY . /code/
COPY ./compose/celery/*.sh /code/
RUN sed -i 's/\r//' celery.sh \
    && chmod +x celery.sh \
    && sed -i 's/\r//' celery-beat.sh \
    && chmod +x celery-beat.sh

Другие файлы для сельдерея:

  • compose/celery/celery.shСценарий запуска Celery.
  • compose/celery/celery-beat.shСценарий запуска для celery-beat.

Напишите файл конфигурации запуска Compose

Конфигурация docker-compose выглядит следующим образом:

version: '2'

services:
  redis:
    image: redis
    ports:
      - "6379:6379"

  db:
    restart: always
    image: mysql:5.7.19
    # command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./compose/mysql/:/etc/mysql/conf.d
      - ./db:/var/lib/mysql
    # for test
    ports:
      - "127.0.0.1:3307:3306"
      # (HOST:CONTAINER)
    env_file:
      - .env

  web:
    # restart: always
    build:
      context: .
      dockerfile: ./compose/web/Dockerfile
    command: sh gunicorn.sh # ["/bin/bash", "gunicorn.sh"]
    ports:
      - "8080:8002"
      # (HOST:CONTAINER)
    volumes:
      - ./logs:/var/logs/
      - ./collect_static:/code/collect_static
      - ./static:/code/static
      - ./templates:/code/templates
      - ./uploads:/code/uploads
    env_file: .env
    depends_on:
      - redis
      - db

  nginx:
    restart: always
    image: nginx:1.13.0
    volumes:
      - ./compose/nginx:/etc/nginx/conf.d/
      - ./staticfiles:/code/staticfiles
      - ./logs:/var/log/nginx
    ports:
      - "80:80"
      # (HOST:CONTAINER)
    depends_on:
      - web

  celery:
    build:
      context: .
      dockerfile: ./compose/celery/Dockerfile
    command: sh celery.sh
    volumes:
      - ./logs:/var/logs/
      - ./uploads:/code/uploads
    depends_on:
      - redis
      - db
    env_file: .env

  celery-beat:
    build:
      context: .
      dockerfile: ./compose/celery/Dockerfile
    command: sh celery-beat.sh
    volumes:
      - ./logs:/var/logs/
    depends_on:
      - redis
      - db
    env_file: .env

Рабочий процесс и бит Celery Здесь мы используем один и тот же образ Dockerfile, по принципу один образ и один процесс, запускаем два контейнера для запуска рабочего и битового процессов соответственно.

скомпилировать тест

После написания конфигурационного файла скомпилируйте тестовый образ и запустите:

docker-compose build 
docker-compose up  # 前台运行 
docker-compose up -d  # 无误后可后台运行

docker-compose psВы можете увидеть запущенный контейнер:

$ docker-compose ps    
             Name                           Command               State            Ports          
--------------------------------------------------------------------------------------------------
dockerdjangodemo_celery-beat_1   sh celery-beat.sh                Up                              
dockerdjangodemo_celery_1        sh celery.sh                     Up                              
dockerdjangodemo_db_1            docker-entrypoint.sh mysqld      Up      127.0.0.1:3307->3306/tcp
dockerdjangodemo_nginx_1         nginx -g daemon off;             Up      0.0.0.0:80->80/tcp      
dockerdjangodemo_redis_1         docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp  
dockerdjangodemo_web_1           /bin/bash entrypoint.sh sh ...   Up      0.0.0.0:8080->8002/tcp  

Сопоставленный порт можно настроить в соответствии с вашей реальной ситуацией.

вопрос

Ниже приведены некоторые вопросы, на которые необходимо обратить внимание в процессе строительства.

проблема с кодировкой mysql

Изображение mysql, предоставленное докером, кодировка по умолчаниюlatin1, при сохранении китайского языка отображаются искаженные символы. Официальная предоставляет возможность изменить метод кодирования, указать формат кодирования после запуска скрипта, документ виденздесь. За версией контейнера mysql версии 5.7.19 могут следовать параметры непосредственно после команды в docker-compose.yml.--character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci. Таким образом, просто измените кодировку на стороне сервера. Все форматы кодирования можно указать напрямую, переопределив файл конфигурации.

Конфигурация выглядит следующим образом:

[mysqld]
default-storage-engine=INNODB
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
init-connect='SET NAMES utf8mb4'
init_connect='SET collation_connection = utf8mb4_general_ci'
skip-character-set-client-handshake  # 跳过客户端的编码配置,客户端直接使用服务端的编码配置
bind-address = 0.0.0.0

Примечание. Метод файла конфигурации MySQL 5.7.19 успешен, 5.7.4, 5.7.17 не работает, может использоваться для справки.

web дождитесь завершения запуска mysql, прежде чем продолжить

Контейнер mysql не может принимать подключения к базе данных до его запуска.Когда сеть запущена и инициализирована, если база данных не была запущена, веб-контейнер не сможет запуститься и выйти напрямую. Мы можем добавить сценарий обнаружения при запуске веб-контейнера и продолжить работу после подключения базы данных.

Сценарий выглядит следующим образом:

#!/usr/bin/env bash
set -o errexit
set -o pipefail

echo $MYSQL_PASSWORD
echo $MYSQL_DATABASE
echo $MYSQL_HOST
echo $MYSQL_USER
echo $MYSQL_PORT

function mysql_ready(){
python << END
import sys
import pymysql
try:
    conn = pymysql.connect(host="db", port=3306, user="root", passwd="$MYSQL_ROOT_PASSWORD", db='$MYSQL_DATABASE', charset='utf8')
except pymysql.err.OperationalError:
    sys.exit(-1)
sys.exit(0)
END
}

until mysql_ready; do
  >&2 echo "MySQL is unavailable - sleeping"
  sleep 1
done

>&2 echo "MySQL is up - continuing..."

Суммировать

На этом использование докера для развертывания службы стека технологий django завершено, полный код проекта вы можете посмотреть здесь.docker-django-demo.

В статье начали говорить о том, что этот метод развертывания не подходит для онлайн-сервисов производства крупных веб-сайтов, и есть много проблем, таких как слишком высокая связанность и сложное обслуживание. Тем не менее, развертывание собственного стороннего проекта или тестовой среды по-прежнему очень хорошо, когда аппаратные ресурсы ограничены. Помимо уменьшения проблем с развертыванием и созданием среды, миграция также очень удобна.

demoТакже есть некоторые случаи использования docker в среде разработки, но я всегда считаю, что docker больше подходит для деплоя, и он не такой гибкий и удобный, как непосредственно встроенный в среду разработки. Вы можете оставить сообщение, чтобы обсудить опыт использования докера в разработке и развертывании.

Ссылаться на