Pull to refresh

Comments 46

Сейчас надо будет заснуть на 40 секунд, чтобы успела развернуться postgres-ка
Вместо этого для php-fpm можно указать docker-entrypoint файл, в котором проверять доступность постгреса, например:
until pg_isready --timeout=0 --dbname="${DATABASE_URL}"; do
    sleep 1
done
А чем параметр depends_on в docker-compose не подойдёт? Для подобных ситуаций он и нужен.
depends_on на самом деле не проверяет, готова ли база к использованию:
depends_on does not wait for db and redis to be “ready” before starting web — only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.
docs.docker.com/compose/compose-file/#depends_on

Он гарантирует, что один контейнер не запустится без другого, и гарантирует последовательность запуска. Но не гарантирует, что к моменту готовности PHP будет готов и контейнер с СУБД. Я для этого в entrypoint использую https://github.com/vishnubob/wait-for-it, и жду пока не откроются нужные порты.

Да, depends_on не проверяет доступность именно самой БД для использования. Контейнер php разворачивается и так в разы быстрее, чем БД. Плюс ко всему БД контейнер уже является доступным, но при этом сама БД еще не работоспособна. Соответственно depends_on воспринимает ее уже как готовую, так как контейнер то типа готов… и происходит тут коллизия… (((

Решение простое. В постгрессе делаем healtcheck. А depends_on умеет запускать контейнер, когда другой контейнер дал статус «здоров». Проблема только одна: это синтаксис докер-компоуз второй, а не третьей версии (хотя они и развиваются параллельно)

Контейнер php разворачивается и так в разы быстрее, чем БД

Это смотря как у вас организован entrypoint для php-контейнеров. У нас в проектах через entrypoint проходит полный цикл инициализации: обновляются composer-пакеты, накатываются миграции БД, и прочее.

Да, я тоже об этом подумал уже потом ))) Но все никак руки не доходят подправить этот момент )))
Хочу поделиться как я запускаю IDE внутри Докера на Линуксе.

  1. Устанавливаю x11docker.
  2. Создаю Dockerfile с GUI либами необходимыми для IDE, или использую готовый образ.
  3. В проекте создаю скрипт docker/ide.sh. Там делаю проверки и инициализации, в конце запускаю IDE в контаинере.


Примеры

А если не секрет, зачем запускать IDE внутри докера?.. о_О
Разработчики ничего не устанавливают, основная система не засорена либами для разработки. Можно работать над проектами которые требуют разные окружения. Все разработчики, вне зависимости от их дистрибутива линукс, работают в одном и том же окружении. IDE имеет доступ к тулзам используемых в проекте: лучше анализирует код, в консоле IDE можно запускать нужные инструменты, из IDE компилируешь и линкуешь с либами установленные в контейнере (C++), запускаешь приложение/сервер/тесты, дебажиш.

Хорошее решение. Сами танцевали с бубном вокруг иксов в докере. Единственная серьезная проблема — правильный маппинн пользователя внутри докера наружу. Это критично, когда на одном пк (сервере) работает несколько пользователей, а докер, как известно, может на каталоги внутри volume ставить права, отличные от ожидаемых на хост-машине

Можно просто скопировать из контейнера нужные либы (/usr/include, /usr/lib и тд) в хост машину и прокинуть прокси io на исполняемые файлы через docker exec как например сделал в github.com/eduardmatveev/subsys-proxy

Vps? В России разницы между vps и vds нет. Не вводите людей в заблуждение. Вопрос только в технологиях. Т.е. полноценная виртуальная машина — да, докер взлетит. Но у того же Таймвеб были определенные проблемы с бекапом ВМ с докером (особенности qemu agent), которые потом были решены. А другое дело — контейнерная виртуализация (всякие богопротивные openvz): там даже не знаю получиться ли, ХОТЯ ДОКЕР ВНУТРИ ДОКЕРА РАБОТАЕТ!!!!

Да, возможна неточность. Я столкнулся с тем, что, например, на mchost VPS невозможно завести докер. Поэтому решил сообщить об этом людям, чтобы имели в виду, что докер не на любом хостинге взлетит.

Использую docker недавно, в связи с этим 3 вопроса:
  1. Как корректно выставить права в контейнере? Т.к. id пользователей хоста и контейнера не совпадают, периодически возникает ситуация что с хоста нельзя отредактировать какой-либо файл, либо в контейнере ругается composer и т.п.
  2. Как правильно поместить rsa ключ в контейнер? Secrets, конечно, помогает, но его приходится внутри контейнера копировать в $HOME/.ssh и выставлять права. Это лишние телодвижения, плюс есть опасения, что контейнер может попасть на hub.docker.com
  3. Не могу найти вменяемой инструкции по генерации описаний образов на хабе.
1. выполнить `chown` для созданных файлов внутри контейнера / создавать файлы не в контейнере
2. --volume $HOME/.ssh/id_rsa:/root/.ssh/id_rsa:ro
1. выполнить `chown` для созданных файлов внутри контейнера / создавать файлы не в контейнере

Это понятно, хотелось бы более изящное решение. У меня пока есть мысль испльзовать группы и групповые права, но до реализации не дошло.

2. --volume $HOME/.ssh/id_rsa:/root/.ssh/id_rsa:ro

Не для root-а это не сработает (а может, и для него — не проверял). Права выставляются правильные, но владелец же не меняется.
ты можешь заранее раздать права владельцу, как вариант.
Первый вариант слишком замороченный, а вот второй, похоже, самое оно. Спасибо!
  1. Честно говоря сам пока что не до конца решил этот вопрос на проде. На локалке просто 777 выставляю и все. А вот с продом пока что тоже под вопросом.


  2. Я пока что не смог найти лучшего решения, чем расшаривать, на данный момент. На hub.docker.com точно не попадёт


  3. Генерации описаний образов… Ну… Я описание пишу сам в формате как README.md пишется и все.


А «расшаривать» — что Вы имеете в виду? Монтирование? А как быть, опять же, с владельцем? Поменять можно, но он же поменяется и на хосте.

Я описание пишу сам в формате как README.md пишется и все.

А блок с тегами, ссылками на Docker-file? Тоже руками? Плюс там как-то можно это передавать параметром при push-е.
Либо можно указать 7777:80, и тогда ваш сайт будет по url localhost:7777. Это необходимо бывает для того, чтобы несколько проектов можно было разворачивать на одном и том же хосте.
Для запуска нескольких проектов на одном хосте очень удобно использовать контейнер jwilder/nginx-proxy. Грубо говоря, это подготовленный контейнер с nginx, который следит за тем, какие контейнеры запущены и автоматически создает виртуальные хосты для тех, у которых в окружении есть переменная VIRTUAL_HOST

traefik удобнее. Накидываешь правильные labels на контейнеры, немного магии и ПРОФИТ!!! А самое ценное, что трэфик умеет сам получать сертификаты le

traefik удобнее
чем, например? я не набросить, интересно услышать мнение

правильные labels на контейнеры, немного магии и ПРОФИТ
трэфик умеет сам получать сертификаты
принцип работы аналогичный, jwilder — переменные окружения, у traefik метки. Сертификаты letsencrypt тоже оба решения умеют автоматически получать.

При этом traefik медленнее (https://docs.traefik.io/v1.5/benchmarks/):
Traefik is obviously slower than Nginx, but not so much: Traefik can serve 28392 requests/sec and Nginx 33591 requests/sec which gives a ratio of 85%. Not bad for young project :) !
jwilder — это не коробочный nginx или nginx plus. Это минус. Жирный.
Traefik это все умеет из коробки.
Касательно медленнее — я не понял, что это — жалоба или радость? Потому что такая производительность для нового проекта, причем не для highload очень неплоха.
А еще у traefik есть изначальная интеграция с прометеус (жирный плюс) и очень симпатичный дашборд (не секьюрен, но можно самому закрыть его от внешнего мира).

На самом деле попробуйте сами и убедитесь.
Только не используйте его на продакшене в ближайшие пару лет.
Глючное поделие.
Есть конкретные замечания/претензии к нему?
В свою очередь скажу, что я синимум с четырьмя серьезными багами столкнулся в nginx
1. Отвратительно работает с сетью при сколь-либо значимых нагрузках.

2. И крайне чувствителен к ее качеству. Ровно настолько, что в реальном случае была одна «мигающая» машина (вина тоже скорее всего traefik, но так как это не было доказано на 100%, то опустим), которую traefik с некоторой периодичностью переставал видеть. После чего начиналась перестройка маршрутизации у него и на это время ложились все машины.
А поскольку та, самая «мигающая» до завершения перестройки маршрутизации объявлялась вновь… То… Процесс повторялся.

Для тех целей где он себя позиционирует — это недопустимо.
В деве же использовать его удобно — да. Но дев как раз лучше держать близким к продакшену по конфигурации.
надо просто «загуглить» сокращения docker run команды

мне кажется, что наилучший вариант это (или как «один из» вариантов)
docker help run
Быстро, качественно и не нужен интернет.

PS: Временно оказался в стране где доступ к интернету медленный, порой так быстрее ))
Если для локалки
 volumes: - ../:/app
допустимо, то для прод-окружения тянуть код на машину и прокидывать его в контейнер выглядит чуждо самой концепции докера, плюс добавляет сложность при обновлении, когда недостаточно docker service update, но нужно еще и пулить код с гита. Еще одним недостатком такого является чрезвычайная сложность или даже невозможность быстрого отката (blue green deployment). У себя в проекте для fpm и nginx я наследуюсь от соответствующих образов и клонирую при билде код проекта внутрь образа. Из минусов такого подхода — теряется кеш при каждом релизе, но, по-моему, плюсов от такого подхода больше.

P.S. У вас не было проблем с производительностью php при использовании докера? Я, конечно, ожидал оверхеда 5-10%, но по факту у меня докер медленнее натива минимум на 30-50% на одинаковых машинах.
Приветствую, нет, на данный момент никаких проблем нет с производительностью, даже с учетом того, что далеко не все сейчас у меня настроено оптимально, это как бы наброски, которые требуют импрувментов. )))
то для прод-окружения тянуть код на машину и прокидывать его в контейнер выглядит чуждо самой концепции докера

Fian какая правильная концепция?

Отвечу про концепцию. Монтирование кода приложения удобно на этапе разработки, чтобы сразу тестировать правки. На продакшене устанавливать гит, стягивать код из репозитория — лишние действия. браз должен содержать в себе готовое к запуску приложение.

Мы собираем цельный самодостаточный образ с приложением, который содержит всё, что нужно для работы приложения, и потом используем его в кубернетес. Для разработки, понятное дело, код монтируется.
подход понял. А как на практике прокидываете запросы с хоста (боевого) на уже собранный докер? (Первое что в голову приходит nginx проксирование)
Flan можно тоже присоеденюсь с вопросом)
Я правильно понял, вы предлагаете на CI сервере склонить корень проекта в контейнер php и в таком виде запушить его в docker hub?
А как тогда на продакшен сервере этот же контейнер подтянется и поднимется с остальными? Прописывать поднятие всех 3-4 контейнеров одной командой?
Сейчас у меня тоже на продакшене нужно тянуть гит, проект, далее из compose файла и volume'ы все хозяйство поднимается. И я согласен с вами что это неправильный путь
Да, предложение было в том, чтобы код держать изолированно в контейнере. Дополню, что в моем сообщении смысл был не в том, что тянуть гит-репозиторий на сервер это плохо, а в том, что прокидывать код с диска в контейнер на проде это плохо. Плохо или хорошо использовать гит как инструмент доставки того же docker-compose до серверов — я в этом не спец. У нас все деплой-конфигурации вынесены от кода в отдельный репозиторий, но при деплое они все равно тянутся из гита на сервер (на мастер-ноду кластера) и по ним разворачиваются приложения на слейвах.
У меня тут несколько вопросов возникло (не сочтите за глупость, осваиваем только эту неделю):
— working_dir — а для каких целей он нужен в docker-compose.yml, в Dockerfile нужен для выполнения команд в это директории (смена директории), насколько знаю?
— понравилось как упростили работу разработчикам bash-скриптами, можете поделиться?
— replicas — пока что не совсем понял, что будет если увеличить кол-во на одном сервере?
— volumes: — в корне файла docker-composer.yml, зачем он? кажется только у вас его видел
— как же настроить продакшн сервер чтобы уже шла обработка в докере? (у меня конечно получилось это сделать, правда только обработчик php запустил как upstream)
— и самое главное, как обновлять/откатывать на бою?

PS: Спасибо за статью, многое прояснилось ))
  • working_dir нужна, по-моему, не для выполнения команд на этапе сборки, а для задания корневого каталога для приложения при запуске контейнера
  • volumes — это для именованных томов, появилась, в docker-compose версии 3.2, если не ошибаюсь
по поводу sh скриптов в личку ответил )))
replicas — это короче сколько реплик в кластере. Если запустить несколько на одном и том же сервере — ну как бы это тоже имеет плюс в том случае, если один из контейнеров ляжет — то другой возьмет на себя его нагрузку. Но если ляжет сервер, а другого на подхвате нет — то ляжет уже как бы все…

что значит чтобы шла обработка в докере?

Обновлять откатывать на бою… я делаю это через jenkins… То есть у меня репа снаружи докера и всем заправляет Jenkins… Jenkins можно настроить версионностью и выгружать не ветки, а теги… например… )))
Sign up to leave a comment.

Articles