Как устроен боевой проект на docker?
Подскажите пожалуйста примерную структуру проекта. Как я понимаю структуру сейчас:
Сервер Ubuntu:
- Docker:
- Контейнер с приложением (например Django)
- Контейнер с БД
- Nginx
Казалось бы все просто. Но возникает вопрос https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/ Зачем делать отдельный контейнер для NGINX. Идея в том чтобы автоматизировать развертывание? Или внешний NGINX как то работает с контейнером nginx. Вопрос настолько глупый, что поиски ответа не дают результата
Ответы (2 шт):
В принципе, можно NginX и приложение в один контейнер запихнуть, но:
- Это не по канонам микросервисной архитектуры, в которой подразумевается, что каждый микросервис занят чем-то одним. А прокси и приложение всё же разные микросервисы, и недочёт здесь такой – если вам захочется добавить ещё один микросервис, то всё равно придётся доставать NginX в отдельный контейнер. Иначе зачем вообще лезть в микросервисы и Докер :) Особенно это актуально для крупных проектов, где есть какая-то команда или даже не одна.
- Это против советов по эксплуатации Докера, где говорится, что каждый контейнер должен иметь одну команду
RUN/ENTRYPOINT, которая запускает единственный целевой процесс. Здесь важными аргументами будут:- упрощение тестирования,
- упрощение конфигурировния: у каждого контейнера конкретные свои нужные переменные окружения и файлы,
- и эксплуатации: если в контейнере упадёт единственный главный процесс, то упал весь контейнер; но как быть, если процессов больше одного?!
В общем, инкапсуляция рулит, но на деле конечно разные правила и советы нередко нарушаются, что в может быть приемлемым с учётом масштаба и перспектив вашего проекта. И если у вас личный проектик с малой нагрузкой на слабом серваке, код которого небольшой и будет обновляться не часто / без принципиальных изменений, то вполне можно всё запихнуть в один контейнер. Во всех других случаях лучше сделать по качеству :)
Добавляю к ответу @AivanF.
Причины, почему Nginx лучше вынести отдельно
- Nginx может раскидывать нагрузку по сотне контейнеров приложения, не напрягаясь. По ресурсам выгоднее 1 Nginx + 100 App, чем 100 (Nginx + App).
- Каждый сервис пишет лог в stdout или stderr. Оркестраторы типа кубера его вычитывают. Лог будет писаться только Nginx, а приложению придется его писать в отдельный файл, который надо как-то вычитывать, либо слать через syslog. Либо можно настроить приложение писать в лог
/proc/1/fd/1совместно с Nginx (pid основной команды в докере всегда равен 1). Можете войти в контейнер и выполнитьecho foo > /proc/1/fd/1- увидите как это упадет в лог "якобы от Nginx" (посмотреть можно так:docker-compose logs -f --tail 100 nginx). Такой смешанный лог неудобен. В случае разделения на контейнеры все проще, и такой проблемы не будет: пишем в stderr/stdout, кубер вычитывает все отдельно, проблемы нет.
Причины, по которым Nginx лучше засунуть в контейнер приложения
Это случай, когда приложение не будет под нагрузкой. И сложно устроено.
Например, есть готовые образы ELK и GitLab, "все в одном", они запускаются буквально одной командой. Проще создавать, проще запускать, имеют право жить.