Comments 22
Я ни разу не являюсь специалистом по Docker, однако даже мне известно, что размещение более одного контейнера внутри докера, это нарушение самой сути контейнеров. Внутри контейнера supervisord
забирает на себя все функции Docker'a. А процессами должен управлять сам Docker, следить за ними, показывать их адекватные метрики. Если очень хочется сделать такой бандл "все в одном", то пожалуйста — создавайте контейнер, внутрь которого пробрасываете сокет Docker'a, и внутри этого контейнера обычным docker-compose
или без него запускайте сколько угодно контейнеров, связанных между собой, но только непосредственно через Docker! И когда будет нужно, можно делать так же docker exec
на какой-то entrypoint
, а от него пробрасывать команды на целевые контейнеры. Даже такой Docker внутри Docker это гораздо лучше, чем один контейнер с несколькими процессами, у которых Docker даже pid
не знает, тогда зачем Docker нужен?
Описанный в статье инструмент можно использовать только для хоумпейджей или для девелопинга. Но кому оно надо, если Docker используются только в более менее крупных проектах, или просто нормальными системщиками. Все прочие используют "сPanel" или максимум sftp
. А те, кто хотят войти в мир Docker'а начитаются таких статей, и делают неправильно с самого начала.
2. Да, статья именно про окружение для девелопинга
Все в одном здесь вот где:
FROM richarvey/nginx-php-fp
Ну даже учитывая, что это окружение для разработки, то я все равно не вижу в этом смысла. Смысл докера в том, чтобы использовать для разработки то же самое окружение для разработки, что и для продакшена. То есть php должен быть скомпилирован точно так же как для дев окружения, как и для прода. Один и тот же, чтобы не было никаких нюансов. Например, для дева запросы по https работают нормально, а на проде нет, потому что для прода php скомпилирован с другой версией OpenSSL. Вот и ломай потом голову, что не так.
Я правильно понимаю, что разделив nginx и php в разные контейнеры мы получим относительно верный вариант?
И что тогда делать с php-fpm? Его тоже отдельно, чтобы все было по канону?
Правило простое: 1 процесс на 1 контейнер. Если нужно определять свой entrypoint
, то внутри обязательно делать:
#!/usr/bin/env sh
# ...
exec daemon-process
Или если ваш демон не умеет нормально обрабатывать сигналы прерывания(SIGTERM
, например), а такое случается, то можно использовать tini
. Он и pid
передаст куда следует, и за сигналами следить будет, а потом убивать запущенный им процесс. Так как tini
добавили в Docker с версии 1.13, можно вообще просто добавить init: true
для сервиса в docker-compose.yml
, но тогда придется даунгрейднуть формат файла до версии 2.x, или наоборот проапргрейдить до 3.7. (Опцию --init
запуска Docker'a в связи с поддержкой Swarm для docker-compose
сначала удалили, а потом вернули) Между опцией init: true
или модификацией параметров запуска контейнера фактически разницы нет, но в первом варианте вам вообще ничего с имеджем делать не нужно. Для нормальных имеджей ничего дополнительно делать не стоит, там уже все в порядке. Проверить же нормальность можно легко: выполняете docker-compose up
и после завершайте по Ctrl + C
. Если процесс умирает сразу, а не после задержки в несколько секунд, то внутри все правильно, если нет, попробуйте добавить init: true
и процесс будет завершаться сразу, так как им уже будет управлять tini
.
Даже если вам нужно использовать cron
, то, по-хорошему, его нужно запускать не на хосте, а в отдельном контейнере, в него пробрасывать сокет Docker'а, и им же что-то делать через docker-compose
/ docker
. Естественно такой имедж нужно будет создавать с установленным внутри docker
.
Я ни разу не являюсь специалистом по Docker. Страшно подумать что мог бы написать нам в ответ специалист Docker
Но вопрос в том, что стоит ли это делать, если есть гарантии что в продакшене будет точно такая же связка, которая точно не будет менять на протяжении всего проекта?
1. webserver (nginx)
2. php
3. events (nodejs)
4. db
5. cache (redis)
При этом я честно говоря не смог с наскока вынести почтовый сервер в отдельный контейнер, поэтому подсадил его рядом с php (каюсь). Но обещаю исправиться =)
Этот вопрос легко решается пока все находится на машине разработчика, просто монтируем папку с проектом в контейнеры с nginx и php как volume.
Сложность начинается тогда, когда это всё надо перенести с машины разработчика, скажем в Kubernetes. Поэтому я для себя пока остановился на решении с nginx и php в одном контейнере. Т. к. этот вариант показался меньшим злом, по сравнению с теми решениями, что пришли в голову.
Только не из пушки по воробьям получится, для отдачи нескольких файлов разворачивать кластерную ФС? Лишний расход вычислительных ресурсов, снижение надежности и скорости доступа, расходы на администрирование.
Вариант 2. Копировать файлы приложения в оба контейнера (и в nginx и в php), мне как-то тоже не понравился из-за перерасхода дискового пространства.
В итоге я пришел к мысли, что запихать nginx в контейнер к приложению будет наименьшим злом.
Я вообще клонирую мастер и делаю composer install и т.к.
Настройка рабочего окружения в Docker для yii-framework приложения