Pull to refresh

Comments 20

p.s. Спасибо freeman1988 за вычитку наскоро переведённого материала.
У автора получился фарш из всего подряд в одном контейнере, а часть еще и на хост машине — это противоречет идеалогии docker. По-моему должно было получиться так: 1 конейнер — nginx, 2 — mysql, 3 — приложение.
Да, статья выглядит даже вредной — помимо фарша, еще заметил, что мускуль смотрит наружу, что очень не рекомендуется делать, в Dockerfile в конце бессмысленная команда удаления кеша apt и временных файлов, которая на размер контейнера не влияет.
Эта проблема тянется из phusion, которые намешали такую кашу в свой шаблон.
А вообще как лучше хранить БД? Я так понимаю желательно создать для СУБД отдельный контейнер, а куда сами данные девать? Держать в том же контейнере, на хостовой машине или может отдельный контейнер создавать?
Я храню на хост машине, как и логи. Для этого в докере у run есть параметр -v, а в докерфайлах VOLUME. Как это сделать в каком-нибудь кластере CoreOS пока не догадываюсь, ведь там нужно учесть то, что контейнер может запускаться на разных нодах, в зависимости от их доступности.
Отдельный контейнер для СУБД, отдельный контейнейр чисто для VOLUME файлов данных. Контейнер СУБД юзает volume из контейнера данных. Если надо бэкапиться — запускаете отдельный контейнер, который юзает этот же volume из контейнера данных, и внутри этого нового контейнера запускаете бэкап.
А гему при каждом деплое будут заново устанавливаться?
Можно по разному сделать — если вы уверены, что важи гемы не будут меняться их можно загнать в базовый docker-образ, и тогда деплой будет оч. быстный, если нет — тогда да, будут каждый раз устанавливаться.
А можно сделать чтобы bundle install работал как обычно. Устанавливал только те гему, которые изменились?
Так можно сделать, но это опять же противоречит идеологии докера. По задумке, при каждом деплое конейнер пересоздается, это (а так же то, что он выполняет только одну задачу) позвол держать его чистым, незагаженным, имеющим всегда одно и то же контролируемое окружение.
Понятно, а есть ли какой-то способ не противоречить идеологии докера и иметь возможность деплоить быстро? Например, если мне нужно сделать хотфикс я не хочу ждать, пока докер устанавлилвает десятки гемов и компилирует native extensions.
Может быть кто-то другой ответит. Я просто nodejs-стек использую — там установка npm-пакетов достаточно быстро происходит. Не пытался это как-то оптимизировать.
Есть — собирать новый образ (долго), после чего останавливать запущенный контейнер (быстро) и тут же запускать его по-новой на уже собранном новом образе (так же быстро). Итого имеем очень маленький даунтайм
Прикол докера в том, что после каждой команды Dockerfile результирующий контейнер кешируется. Т.е. если у вас был такой Dockerfile
RUN apt-get update
RUN apt-get install package1 package2

а поменялся на такой
RUN apt-get update
RUN apt-get install package1 package2 package3

то при сборке следующей он возьмет тот контейнет, который создался в прошлый раз после apt-get update и накатит на него apt-get install package1 package2 package3. Вы можете сделать по-другому:
RUN apt-get update
RUN apt-get install package1 package2
RUN apt-get install package3

Тогда при сборке он возьмет состояние после RUN apt-get install package1 package2 и накатит на него только apt-get install package3.

Если у вас было
RUN command1
ADD directory or file
RUN command2

то при следующей сборке docker посчитает хеш добавленных в ADD файлов, и будет выполнять RUN command2 только если в них что-то поменялось. Т.о. я прихожу к такому предпочитаемому формату Dockerfile

RUN install and configure all server software (типа поставить интерпретатор и fcgi-демон для нужной технологии)
ADD vendors config (у нас в PHP это composer.json + composer.lock, в nodejs это будет package.json в каждой технологии свои)
RUN install vendors (composer install, npm install etc)
ADD static files (js, img, css, scss etc)
RUN compile static files (minify js css, etc)
ADD all source code


Т.о. получается, что при небольшом изменении кода, если это не затрагивает статику и вендоров, контейнер будет билдиться практически моментально (и соответственно деплоиться тоже, т.к. при деплое докер загрузит только изменения, связанные с добавлением других source файлов). Если вы измените JS, то билд будет немного дольше — нужно будет перекомпилировать все JS. И только если измените список вендоров, вам придется перекачивать этих вендоров заново.
Кстати, а зачем вообще, деплоить rails приложение в докер?
Изолированность, переносимость, масштабируемость. Смысл примерно такой же, как и в том зачем программы делить на слабосвязные модули/функции и т.д. Посто таким образом можно строить более сложные системы.
В данном методе профита вообще никакого. Как писали выше — только вред.
Кроме того, самое интересное — как деплоить и откатываться автоматически аналогично капистрано — не раскрыто.
Ну и гзшечками код раскидывать — тоже не лучший вариант. Привычнее git и cached copy в контейнере или volume.
Переносимость — можно использовать chef. Масштабируемость вообще к докеру отношения не имеет.
Спасибо, что перевели статью. Статью без лучших практик и с нарушением их.
Лучше использовать doker для контениризации, а деплоить Rails-приложения с помощью capistrano.
Sign up to leave a comment.

Articles