Виртуализация процесса разработки, часть 1: Docker

Привет, меня зовут Андрей Двояк. Я специалист по комплексной разработке веб-приложений в украинском стартапе Preply.com, это платформа для поиска репетиторов. За последний год наша команда выросла, и для облегчения процесса адаптации новых разработчиков мы решили организовать и стандартизировать наш процесс разработки.

Мы посвятили много времени поиску лучших методик и обсуждению с другими командами, стремясь выяснить, какой путь наиболее эффективен для организации процесса разработки и распределения доступа, особенно когда ваш продукт разделен на несколько микросервисов. В итоге мы остановились на двух основных технологиях: Vagrant и Docker. Вы можете прочитать обо всех аспектах и особенностях у самих создателей этих сервисов на StackOverflow.

В этом руководстве я покажу вам, как «докеризировать» ваше приложение, чтобы вы таким образом могли удобно и просто распространить и развернуть его на любой машине, поддерживающей Docker.

Прежде, чем начать

В этом руководстве мы будем работать с простым приложением Django с базой PostgerSQL и Redis в качестве брокера для выполнения задач Celery. Также мы используем Supervisor для запуска нашего сервера Gunicorn. Мы будем использовать технологию Docker Compose, чтобы организовать работу нашего мультиконтейнерного приложения. Обратите внимание, что Compose 1.5.1 требует Docker 1.8.0 или более поздние версии.

Это поможет нам запустить приложение Django, PostgreSQL и Redis Server и Celery Worker в отдельных контейнерах и связать их между собой. Чтобы реализовать это все, нам нужно всего лишь создать несколько файлов в корневом каталоге вашего проекта Django рядом с файлом manage.py):

  1. Dockerfile — для создания финального образа и загрузки его в DockerHub;
  2. redeploy.sh — для развертывание в обеих средах DEV и PROD;
  3. docker-compose.yml — организовать работу нескольких контейнеров;
  4. Vagrantfile — предоставить виртуальную машину для среды разработки.

Мы используем переменную RUN_ENV для определения текущей среды. Вы набираете на клавиатуре export RUN_ENV=PROD на рабочем сервере и export RUN_ENV=DEV на виртуальной машине Vagrant.

Docker

Как вы, возможно, уже знаете, о Docker нужно знать две вещи: образы и контейнеры. Мы создадим образ, основанный на Ubuntu с установленными Python, PIP и другими инструментами, необходимыми для запуска вашего приложения Django. В этом образе будет предустановлено всё, что необходимо. Этот образ направим в публичное хранилище в DockerHub. Имейте ввиду, что этот образ не содержит ни одного файла вашего проекта.

Мы договорились хранить наш образ на DockerHub всегда обновленным. С этого образа мы загрузим контейнер, пробрасывая специфические порты и монтируя ваш локальный каталог с проектом к какой-то папке внутри контейнера. Это означает, что файлы вашего проекта будут доступны внутри контейнера. Никакой необходимости копировать файлы! Это очень удобно для процесса разработки, потому что вы можете вносить изменения в ваши файлы, и они сразу же будут изменены в работающем контейнере Docker, но это неприемлемо в реальной рабочей среде.

Как только вы запустили контейнер, мы запустим Supervisor с вашим сервером Gunicorn. Как только вы захотели сделать повторное развертывание, мы извлечем новые данные из GitHub, остановим и удалим существующий контейнер и запустим совершенно новый контейнер. Настоящее волшебство!

Установка Docker и Docker-Compose

Прежде чем начать, нам нужно установить Docker и Docker-Compose на наш локальный компьютер или сервер. Ниже указан скрипт, который это делает на Ubuntu 14.04:

sudo -i
echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
curl -sSL https://get.docker.com/ | sh
curl -L https://github.com/docker/compose/releases/download/1.5.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
usermod -aG docker ubuntu
sudo reboot

Тут ubuntu — ваш текущий пользователь.

Если ваша текущая среда разработки не Ubuntu 14.04 — тогда вам будет лучше использовать Vagrant для создания этой среды. Подробнее расскажу в следующей статье.

Образ Docker

Во-первых, для подготовки проекта к развертыванию докером нам нужно создать образ при помощи только Python, PIP и нескольких зависимостей, необходимых для запуска Django.

Давайте создадим новый докер файл под названием Dockerfile в корневом каталоге проекта. Это будет выглядеть так:

FROM ubuntu:14.04
MAINTAINER Andrii Dvoiak
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
RUN apt-get update
RUN apt-get install -y python-pip python-dev python-lxml libxml2-dev libxslt1-dev libxslt-dev libpq-dev zlib1g-dev && apt-get build-dep -y python-lxml && apt-get clean
# Specify your own RUN commands here (e.g. RUN apt-get install -y nano)

ADD requirements.txt requirements.txt
RUN pip install -r requirements.txt

WORKDIR /project

EXPOSE 80

Вы можете указать ваши собственные команды RUN, например, установить другие необходимые инструменты.

Затем вам нужно создать образ из этого, используя команду:

docker build -t username/image

Тут username — ваше имя пользователя Dockerhub и image — название вашего нового образа для данного проекта.

Когда вам успешно удалось создать основной образ, лучше будет вам загрузить в облако DockerHub. Это можно сделать командой docker push username/image. И не переживайте, в этом образе нет никакой информации из вашего проекта (кроме файла requiremets.txt). Если вы используете приватное хранилище DockerHub, удостоверьтесь в исполнении docker login перед загрузкой/выгрузкой образов.

Организация работы контейнеров

Итак, на данном этапе мы можем запустить наш контейнер с приложениям Django, но нам также нужно запустить некоторые другие контейнеры c Redis, базой данных PostgreSQL и Celery Worker. Чтобы упростить этот процесс, мы воспользуемся технологией Docker Compose, которая позволяет нам создать простой файл YML с инструкциями о том, какие контейнеры запускать и как линковать их между собой.

Давайте создадим этот волшебный файл и назовем его по умолчанию docker-compose.yml:

django:
  image: username/image:latest
  command: python manage.py supervisor
  environment:
    RUN_ENV: "$RUN_ENV"
  ports:
   - "80:8001"
  volumes:
   - .:/project
  links:
   - redis
   - postgres

celery_worker:
  image: username/image:latest
  command: python manage.py celery worker -l info
  links:
   - postgres
   - redis

postgres:
  image: postgres:9.1
  volumes:
    - local_postgres:/var/lib/postgresql/data
  ports:
   - "5432:5432"
  environment:
    POSTGRES_PASSWORD: "$POSTGRES_PASSWORD"
    POSTGRES_USER: "$POSTGRES_USER"  

redis:
  image: redis:latest
  command: redis-server --appendonly yes

Как вы видите, мы запустим четыре проекта под названиями django, celery_worker, postgres и redis. Эти названия важны для нас.

Итак, во-первых, наш файл загрузит образ Redis из dockerhub и запустит из него контейнер. Во-вторых, он загрузит образ Postgres и запустит контейнер с закрепленными данными из радела local_postgres. О создании локальной базы данных расскажу подробней в следющей статье.

Затем, этот файл запустит контейнер с нашим приложением Django, направит 8001-й порт изнутри на 80-й снаружи, свяжет ваш текущий каталог прямо с папкой /project внутри контейнера, пролинкует его с контейнерами Redis и Postgres и запустит супервайзера. И последнее, но не менее важное — наш контейнер с celery worker, который также пролинкован с Postgres и Redis.

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

Если вы назвали проект Redis Server именем redis в файле YML — вам нужно указать redis вместо localhost в вашем settings.py чтобы позволить вашему приложению Django подсоединиться к redis:

REDIS_HOST = "redis"
BROKER_URL = "redis"

То же с базой данных Postgres — используйте postgres вместо localhost:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'database_name',
        'USER': os.getenv('DATABASE_USER', ''),
        'PASSWORD': os.getenv('DATABASE_PASSWORD', ''),
        'HOST': 'postgres',
        'PORT': '5432',
    }
}

Скрипт для повторного развертывания

Давайте создадим скрипт для повторного развертывания в один клик (давайте назовем его redeploy.sh):

#!/bin/sh
if [ -z "$RUN_ENV" ]; then
    echo 'Please set up RUN_ENV variable'
    exit 1
fi

if [ "$RUN_ENV" = "PROD" ]; then
    git pull
fi

docker-compose stop
docker-compose rm -f
docker-compose up -d

Давайте проверим, что он делает:
— Он проверяет, установлена ли переменная RUN_ENV и совершает выход, если нет
Если RUN_ENV установлена на PROD, он сделает команду ’git pull’ чтобы получить новую версию вашего проекта;
— Он остановит все проекты, указанные в файле docker-compose.yml;
— Он удалит все существующие контейнеры;
— Он запустит новые контейнеры.

Итак, это выглядит достаточно просто: чтобы сделать повторное развертывание, вам нужно всего лишь запустить ./redeploy.sh. Не забудьте дать права на исполнение (chmod +x redeploy.sh) этому скрипту и всем другим скриптам, описанным в инструкции.

Чтобы сделать быстрое повторное развертывание, используйте эту команду:

docker-compose up --no-deps -d django

Развертывание внутри контейнера

Нам нужно всего лишь запустить супервайзера для того, чтобы собственно запустить наш сервис внутри контейнера: python manage.py supervisor. Если вы не используете супервайзер, вы можете просто запустить ваш сервер вместо супервайзера.

Если же вы пользуетесь супервайзером, давайте посмотрим на файл ’supervisord.conf’:

[supervisord]
environment=C_FORCE_ROOT="1"

[program:__defaults__]
redirect_stderr=true
startsecs=10
autorestart=true

[program:gunicorn_server]
command=gunicorn -w 4 -b 0.0.0.0:8001 YourApp.wsgi:application
directory={{ PROJECT_DIR }}
stdout_logfile={{ PROJECT_DIR }}/gunicorn.log

Итак, супервайзер запустит ваш сервер Gunicorn с 4 работающими процессами и связанным портом 8001.

Процесс разработки

Чтобы зайти на ваш локальный сервер, пройдите по 127.0.0.1:8000.

Для повторного развертывания локальных изменений сделайте:
sh redeploy.sh

Чтобы просмотреть все логи в вашем проекте, выполните:
docker-compose logs

Чтобы быстро реализовать повторное развертывание изменений, используйте:
docker-compose restart django

Чтобы подсоединиться к Django — просто подсоединяйтесь (если ваш работающий контейнер назван CONTAINER):
docker exec -it CONTAINER python manage.py shell

Чтобы создать изначального суперпользователя:
from django.contrib.auth.models import User; User.objects.create_superuser(’admin’, [email protected]’, ’admin’)

Выполнить миграцию:
docker exec -it CONTAINER python manage.py schemamigration blabla —auto

Или вы можете подсоединиться к bash внутри контейнера:
docker exec -it CONTAINER /bin/bash

Вы можете сохранить вашу локальную базу данных в файл .json (вы можете указать таблицу для сохранения):
docker exec -it CONTAINER python manage.py dumpdata > testdb.json

Или вы можете загрузить данные в вашу базу данных из файла:
docker exec -it CONTAINER python manage.py loaddata testdb.json

Используйте эту команду для мониторинга статуса ваших работающих контейнеров:
docker stats $(docker ps -q)

Используйте эту команду для удаления всех остановленных контейнеров:
docker rm -v `docker ps -a -q -f status=exited`

Вы можете играться с вашими контейнерами как вам захочется. Здесь — полезный Docker cheat sheet.

GIT

Когда сервер работает, он будет создавать дополнительные файлы, такие как .log, .pid и так далее. Вам не нужно их включать в репозиторий. Не забудьте создать файл .gitignore:

.idea
db.sqlide3
*.pyc
*.ini
*.log
*.pid
/static
.vagrant/

Статические файлы

У вас могут обнаружиться некоторые проблемы в работе со статическими файлами на рабочем сервере при использовании только gunicorn, поэтому не забудьте создать пустую папку /static/ в вашем корневом каталоге проекта с файлом __init__.py для обслуживания из него статики.

По этой схеме ваш файл settings.py должен включать:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

И для обслуживания статики с помощью gunicorn на рабочем сервере добавьте это в конец файла urls.py:

SERVER_ENVIRONMENT = os.getenv('RUN_ENV', '')
if SERVER_ENVIRONMENT == 'PROD':
    urlpatterns += patterns('', (r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), )

Или же вы можете пользоваться другими сервисами для обслуживания статических файлов, например, использовать сервер nGinx.


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

Все про українське ІТ в телеграмі — підписуйтеся на канал DOU

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному4
LinkedIn



69 коментарів

Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.

Андрій, дякую за статтю.
Запрошую усіх кому цікаво прокачатись в роботі з Docker на майстер-клас frameworksdays.com/event/mk-docker.

нарешті вже можна забути про лінковку, з релізом 1.9 нарешті multi host networking

Как у меня это обычно и бывает, запнулся на раннем этапе. Терминал с грустью уведомил меня, что Docker поддерживает только 64-битные системы. А у меня таки 32-битная. Убунту 14.04.

может virtual box поставить? :) как на вин/маках

не знаю, хотелось специально найти применение лэптопу-старичку, 10 лет уж. в документации не увидел, что докер не поддерживает 32-битные системы, ослеп я чтоли.

я думаю что многие уже просто не учитывают что кто-то использует 32 битные системы в связи с их неактуальностью

Unsupported еще не значит что это невозможно в принципе. Вся соль истории — в поддержке репозитория совместимых 32битных образов (Более детально о проблеме здесь: github.com/...36#issuecomment-44315774

А вот если у вас есть «час та натхнення», то все можно отлично запустить
mwhiteley.com/...08/31/docker-on-i386.html

Вас ждет сборка go + docker из исходников а также подготовка базового 32битного образа linux.

благодарю, понятия правда не имею что из себя представляет go, но разобраться, думаю, можно)

Как вы считаете, если для дев среды использовать допольнительный docker-compose.dev.yml с переопределением конфигурации для celery и для django. А именно добавить volumes и расшарить общую директорию (c кодом проекта) с хост машиной. Это даст возможность не останавливая контейнеры, отслеживать изменения, и автоматически перезагружать celery и gunicorn.

Так, ми так і робимо. Гунікорн можна налаштувати так, щоб він сам рестартився коли міняється код.

Если используется докер на маке учтите что его вольюмы очень медленные

Это потому что нет Docker под OS X. boot2docker ни что иное, как загрузка VM’ки с Linux, на котором крутится Docker демон. Разумеется, волюмы OS X -> VM -> Docker будут медленными. Это же применимо и к работе с boo2docker под Windows.

github.com/mist64/xhyve пробовали?
Не факт что это шило на мыло — но в теории должно быть чуть быстрей чем через VirtualBox

Вообще конечно это плохая практика — шарить код с хост машины в контейнер. В случае развертывания проекта на кластер или например автоматической миграции контейнеров между физическими машинами такой подход вылазит боком, так как идея self-contained никуда не девалась.
Другое дело что если речь идет о паре машин, или дев-среде — то подобное очень удобно. Сам использую и для разработки и для продакшна

Спасибо за статью, хороший вариант если нужно обеспечить стандартное окружение которое можно быстро и повторяемо разверноуть. Я, для аналогичного стека, для dev окружения еще контейнер с nginx использую для раздачи статики и стартую окружение через ansible .... а вот питон не в контейнере, только pyenv ... но у нас нет разработчиков с windows :) .... ну а продакшен просто на стейтлес инстансах ec2 под балансировщиком + RDS + SQS и кеш. Конфигурация инстансов через ansible и вот тут какраз можно поднять, используя Vagrant, полную копию инстанса как на продакшене но локально. А так для постояннной работы с проектом pyenv както привычней и немного шустрее :)

Щодо pyenv, то ось плюси і мінуси нашого стеку:
Мінус: ми поки не навчилися конектити IDE-шку всередину контейнера, щоб вона бачила встановлений там пітон та інші ліби.
Плюс: новому програмісту в команді достатньо виконати дві команди щоб в нього все запрацювало:

git clone ...
./redeploy.sh

ну с плюсами полностью согласен :)
с минусом впринципе тоже ... но когда думал как это сделать .. да и еще какбы все в процессе и изза вот этого плюса всеравно прийдется реализовать как время появится :)
так что есть идея юзать отдельный контейнер с volume в который ставить окружение питона ... ну и там уже локально с правами немного поигратся чтоб редакторы и ide его видели .. но еще не пробовал ... ну и pyCharm вроде както работать умеет но тоже не пробовал еще

Если у вас PyCharm то можно пробросить ssh внутрь контейнера (через VirtualBox порт-форвардинг) и подключить «Remote Python Interpreter».
Я такое пробовал для удаленных виртуальных машин на AWS — единственный минус, довольно долго раздупляется из-за медленной сети, но на локалхосте должно быть все шустро.

Спасибо за статью и проект, о котором как раз на днях писал: thinking.bohdanvorona.name/study-english-2016

Использую уже как пол года вот этот скрипт см. статью. Папка с настройками расположена в папке с проектом.
habrahabr.ru/post/247547

приятно, что моей балалайкой кто-то еще кроме меня пользуется и она кому-то полезна
кстати, я переодически обновляю скрипты и добавляю новые фичи, которые мне были актуальны в моей разработке. следите за обновлениями dvapelnik/efig
если Вы используете мои же образы для докера dvapelnik/docker-lap

Спасибо за скрипт :) Образы использую свои, по сути для меня это инструмент для быстрого переключения между проектами, один раз настроил , потом быстро sudo ./efig.sh :)

всегда пожалуйста
я дополнительно вынес efig.sh в ~/bin/efig чтобы не использовать локальный скрипт и настроил PhpStorm для этого всего дела прямо из IDE

PS странно тут работает парсер и не понимает он меня — слишком он умный

Не забывайте про проблему PID 1 и zombie процессов, поэтому желательно поставить pip install dumb-init и enrypoint запускать как dumb-init python manage.py supervisor

Отлично подметили. Сам недавно лечил эту проблему — хорошая практика это конечно 1 процесс — 1 контейнер, но иногда очень хочется запускать паралельно еще что-то мелкое вспомогательное, например crond.
Я решил через github.com/nickstenning/honcho, это простой Procfile process менеджер, конфигурация для него создается сразу башем из Dockerfile и она намного проще чем конфиги например для supervisord (который тоже часто советуют для таких случаев).

Мы для дева тоже используем вагрант и докер. Примерно то же самое что и у вас (Python + Django + celery)...

Для деплоя на продакшне очень активно думаем. Смотрели на:
— Netflix Spinnaker ( не умеет докер из коробки)
— AWS ECS (смотрели бегло. Мы очень хотим canary deployment, а оно вроде так не умеет)
— смотрим на Kubernetes + Fabric8.io

Очень актуальный вопрос сейчас — как конфигурировать контейнеры при запуске (создание конфиге для Джанго, Целери...), потому как код для платформы у нас один, соответственно контейнер готовим тоже один, но от зависимости того что за микросервис мы хотим сделать — генерируем тот либо иной конфиг. Конфиг — это не тупо база/логин/пароль..., а огромный такой себе json файл..

Есть у кого-нибудь мнения н счёт Consul от Hashicorp или Netflix Eureka?

пользуюсь consul и consul template для формирования конфига. Основное неудобство, что в описание сервиса сильно информации не добавить, поэтом приходиться дублировать в kv хранилище основные сервисы.

Eureka дуже проста штука — регаєш там сервіс і потім по апі або через існуючі сдк отримуєш інстанс потрібного тобі сервісу по імені. Такий собі маленький DNS. Працює без проблем, граблі є тільки з тим щоб зарегати правильний ІР якщо твій сервіс крутиться всередині докер контейнера на EC2 інстансі, але і те просто вирішується.

AWS ECS
Ця штука взагалі більше для організації якихось обчислень типу «підняли 100 інстансів по графіку, запустили на них джобу, порахували, погасили». Для керування інфраструктурою веб-сервісу воно взагалі не підходить бо там ні дашбордів нормальних, нічого немає. Принаймні мені так здалося. Живемо поки що так само як і автор на ElasticBeanstalk.
— Netflix Spinnaker ( не умеет докер из коробки)
В роадмапі але не пріоритет. Не вміє canary.
AWS ECS
Не вміє canary і не має нормальної консолі, все треба робити через скріпти. Зате амазон зробив свій хостинг для контейнерів що разом з ECS дає непогані результати при коректному приготувані. До речі я нижче писав про те що воно вміє підіймати інстанси, так от — не вміє :) Ми якраз зараз розглядаємо його як основний сервіс тому що можна навчити його робити blue/green (через тону скріптів, нажаль) і має версіонування тасок.
Netflix Eureka
Там дуже простий апі, прикрутив його до Python аплікейшенів без проблем. Той py-клієнт який є на гітхабі — з багами, але в мене руки не дійшли туди PR зробити.

Спасибо за статью. Есть одно замечание по поводу:

echo ’debconf debconf/frontend select Noninteractive’ | debconf-set-selections

я бы не советовал такое выполнять на пользовательской машине. По крайней мере без четкого осознания что оно сделает. Гораздо лучше для неинтерактивной установки использовать переменные окружения как

DEBIAN_FRONTEND=noninteractive

Конечно, в Докер контейнере, где мы планируем запускать только свое приложение — разговор другой.

Спасибо за статью. Есть вопрос по поводу Vagrant. Зачем он нужен если для запуска проекта все можно развернуть через Docker? Или вы рабочую машину (вместе с IDE) запускаете с Vagrant образа?

Чесно кажучи, його взагалі не потрібно якщо ваша машина підтримує докер. Якщо у вас віндовс — то Vagrant найлегший спосіб підняти віртуалку з ubuntu та докером. Якщо ж у вас Мак або ubuntu — то проблем немає, використовуйте тільки Докер.
В наступній частині статті я опишу як правильно запускати Vagrant та монтувати файли/директорії.

Спасибо, так и думал. У меня OSX, но для Windows уже тоже Docker Toolbox есть, так что думаю на Windows тоже можно обойтись без Vagrant.

на маке одним докером не получится. Тоже нужен Docker Machine

Я це і мав на увазі. До речі, Docker Machine піднімає віртуалку з мінімальними характеристиками. Для збільшення потужності, сконфігоруйте, напряклад, ось так:

docker-machine create —virtualbox-cpu-count=4 —virtualbox-memory 4096 —driver virtualbox default

Я и не писал про «одним докером». Docker Toolbox включает в себя все необходимое, включая Docker Machine.

Просите, я комментировал выше

Якщо ж у вас Мак або ubuntu — то проблем немає, використовуйте тільки Докер.
Просто попал не туда и не заметил

Странный выбор для запуска на винде. Используйте лучше Docker Machine

Vagrant в чистому вигляді взагалі непотрібен, якщо використовувати Docker Toolbox

Чи розлядали Kubenetes замість Docker compose?

Ми використовуємо Docker Compose лише для локальної розробки. Це найлегший спосіб. На продакшені наші контейнери оркеструє AWS Elastic Beanstalk. Поки Kubernetes не пробували.
В принципі, це відкрита тема. Якщо ти працював з Kubernetes, опиши свої враження.

Kubernetes корисний коли вже багато сервісів. Кожен сервіс має свій опис, подібно до як Docker compose + там же вказуєш скільки інстансів його треба. Kubernetes це все менеджить і слідкує, щоб нічо не падало. Має також service discovery і load balancer.
З мінусів проект ще відносно новий, так не все завжди гладко. Для дева дійсно забагато буде.

Як ви збиєтесь скейтили цей метод коли сервісів 20+? Локально стільки докерів потягне?

Ну не начинать же с монстра в расчете что когда-то дорастут до состояния когда он понадобится. be agile.

Я й не писав починати з монстра. Мені цікаво, як цей метод скейлиться для більшої саме для девелопменту. Може і нам підійде.

На текущем проекте запускаю 23 контейнера на локальной машине. Сами контейнеры довольно легковесные, но 23 сервиса — это 23 отдельных приложения, поэтому ресурсоемко. Если запускать что-то легкое, то думаю на среднем ноутбуке можно поднять 100+ контейнеров.

Питання трохи не в тему, але чисто з цікавості — ви рахували наскільки дорожче виходить використання AWS Elastic Beanstalk порівняно з аналогічним конфігом але просто через docker-compose на звичайній EC2 ноді?

Рахували, AWS Elastic Beanstalk безплатний, ми платимо лише за ресурси які він використовує(ec2, s3, cache, rds). Тобто ціна по факту та сама, але зручніше.

хм, цiкаво.
А можна коротко — в чому основна зручнiсть?

Kubenetes слишкой сложный и тяжолый для дев енвайрмента. Особенно если у вас прод не на нем.

Чем он сложный и тяжелый? Создал как минимум мастер + 2 ноды, настроил pod,pv,rc,lb

Почему выбрали gunicorn, а не uwsgi?

Так історично склалося. Вважаєш uwsgi краще? Аргументуєш?

blog.kgriffs.com/...n-vs-node-benchmarks.html

ivan-site.com/...nicorn-for-async-workers

“As you can see uWSGI has a clear advantage over gunicorn here being able to handle almost twice the number of requests per second for this simple example. Also, our applications saw worse performance in gunicorn using gevent and eventlet asynchronous workers”

Тем не менее:
www.digitalocean.com/...d_wsgi-uwsgi-and-gunicorn

“Gunicorn is also very light weight. Whether it is faster than uWSGI is very much up for debate. Much of this has to do with how you configure Gunicorn or uWSGI. Both can reach very impressive levels of performance, though some have mentioned that Gunicorn works better under high load.”

Как говорится, it depends.

Хороший опис і інструкція для початку роботи з докером!
Ще, для кращого розуміння, круто було б доповнити статтю інформацією як запустити все без docker-compose.
Тобто спочатку запуск і лінкування контейнерів вручну, а тоді альтернативний і простіший варіант з docker-compose. Це вносить ясності. Так як при запуску docker-compose up -d запускаться одразу кілька команд і важливо розуміти які, як на мене.
Ну і вказать те, що docker-compose все ж не рекомендовано використовувати на prod-серверах.

а почему docker-compose не рекомендован в продакшене?

об этом гласит официальная документация:

docs.docker.com/compose/production
Compose is still primarily aimed at development and testing environments. Compose may be used for smaller production deployments, but is probably not yet suitable for larger deployments.

Вообщето, есть Docker Swarm, который как раз для продакшн и предназначен и может быть альтернавтивой кубернетису. Тут его весьма хвалят technologyconversations.com/...bernetes-vs-docker-swarm

Да Swarm нормально работает, особенно после 1.0 релиза

Ну мы использовали докер на проде с версии 0.6 или типа того. Он тогда был тоже не продакшен реди, но ничего — работал нормально.

Тем не менее, как раз вот для smaller production systems его и использую. Просто удобная штука — все что для кластеров и выше заманаешься конфигурировать для простых случаев

Сергій, дякую за коментар. Слушні зауваження. Docker Compose справді не варто використовувати на продакшені, адже він ніяким чином не підтримує контейнери і не піднімає їх знову, якщо вони впадуть. Також, виникають проблема, якщо залінковані контейнери повинні підніматися в певному порядку. Наприклад, спочатку потрібно підняти контейнер з базою, а потім вже апу. Докер Композ по порядку виконає ці дії, проте він не буде чекати коли всередині першого контейнера запуститься і ініціалізується база даних.
Для оркестрації контейнерів на продакшені ми використовуємо AWS Elastic Beanstalk.
Якщо в тебе є досвід роботи з докером на продакшені, поділися будь ласка!

Еще, если много контейнеров, рекомендуют consul (www.consul.io), чтобы DNS сам обновлялся.

використовую docker-compose в продакшнi у зв’язцi з supervisord — проблеми рестарту як мiнiмум вирiшує.

А почему не рекомендовано, если не секрет?

Підписатись на коментарі