Эта статья была впервые опубликована в техническом блоге 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 больше подходит для деплоя, и он не такой гибкий и удобный, как непосредственно встроенный в среду разработки. Вы можете оставить сообщение, чтобы обсудить опыт использования докера в разработке и развертывании.