Comments 36
CMD [ «node», «index.js» ]
Заинтригован. Не могли бы вы дать ссылку на описание этого способа запуска?
CMD это имеется в виду ситнаксис Dockerfile например можно почитать в не моей статье https://habr.com/ru/company/southbridge/blog/329138/
Если основной процесс валится то и контейнер валится. Можно этого избежать если основной просеыы будет например supervisor но это будет уже не docker way
Кстати supervisor это еще один способ запустить то что нужно.
Проблема докер-контейнеров в том что для реальной работы на проде они требуют оркестратор в качестве которого выступает например nomad или cubernetes — которые как раз и следят чтобы процесс был рабочий и в случае ошибки запускают новый процесс. Но по сравнению с pm2 для оркестратура нужно еще очень и очень много чего.
restart always или on failure базовая фича докера. Для перезапуска дополнительно оркестраторы не нужны. Они для реплицирования и обнаружения (связи) сервисов прежде всего
Речь скорее о том что запускать контейнеры на проде командной строкой в 100500 символов не так уж удобно. А от этой командной строки как раз зависит что и как собственно будет работать
Например если я хочу разобраться как работает хостовый не в докере nginx или mysql я изучаю его конфиги. В случае докере мне для этого нужно ещё знать командную строку, dockerfile которого может и не быть в исходниках а где-то взят готовый чужой имидж.
Какие-то надуманные проблемы. Чтобы запускать сервер — надо будет знать 100500 символов настройки этого сервера (установка всего и вся, настройка портов, копирование конфигов). А переехать на другой сервер — это значит опять всё устанавливать и не факт, что что-нибудь не забудется и/или версия пакета не обновится. А с докером: установить докер, скачать проект и запустить подготовленную строку.
Чужой имидж — это просто стандартный официальный имидж от разработчика приложения, который легко настраивается и всегда предсказуемо вебя ведёт. Не представляю, чтобы кто-то использовал какой-то мутный имидж от no-name. Проще самому написать.
Откуда берутся мутные имиджи. Девопс творческий в кавычках и без кавычек человек. Слабо контролиуемый так как в его хозяйство никто не лезет. Фигачит налево и направо кастомные имиджи и заливает их на публичные хабы. Прошли годы. Сломался проект или нужно как Вы справедливо заметели переместить проект на другой сервер. И тут начинаются не надуманные проблемы.
Если в примере имидж — "мутный", то в примере без docker'a — у вас не будет никаких сведений (или очень поверхностных) о конфигурации сервера. Но это крайние случаи — и оба варианта одинаково неприятны. Тут причина не в docker'e, а в девопсе.
В моём опыте не крупных проектов с dockerfile'ами (без выделенного девопса) — они хранятся либо в самом проекте в папке docker, либо в отдельном репозитории той же компании. Это значительно упрощает настройку как локального окружения, так и сервера.
Спасибо что обратили внимание на такую проблему. Я бы все же работал скорее с pm2 например как описано в статье https://en.programqa.com/question/52499715/ т.к. pm2 это (если не под cubernetes) наверное наилучший вариант.
Спасибо за ссылку. Интересный workaround. Попробовал его применить на тестовом сервисе. Добавил в package.json
:
"scripts": {
"safestart":"node --experimental-modules src/app_es6.mjs"
}
и запустил сервис командой:
$ pm2 start npm -- run safestart
Видно, что ES6-приложение запускается:
$ pm2 log
...
/home/alex/.pm2/logs/npm-error.log last 15 lines:
0|npm | (node:11489) ExperimentalWarning: The ESM module loader is experimental.
/home/alex/.pm2/logs/npm-out.log last 15 lines:
0|npm |
0|npm | > pm2es6@0.1.0 safestart /home/alex/work/sof_es6_pm
0|npm | > node --experimental-modules src/app_es6.mjs
0|npm |
0|npm | ES6 app listening on port 3000!
0|npm | Hello World! ES6 module is here.
0|npm | Hello World! ES6 module is here.
0|npm | Hello World! ES6 module is here.
0|npm | Hello World! ES6 module is here.
К сожалению, нельзя использовать возможности кластеризации (-i 4
) — запускается только первый инстанс приложения, остальные сваливаются. Но и то, что есть, гораздо интереснее выглядит, чем forever
или systemd
.
Попробовал так (npm run cluster
):
{
"type": "module",
"scripts": {
"start": "node --experimental-modules app.js",
"cluster": "pm2 -i 4 start npm -- run start"
},
}
Вроде запустилось:
Попробовал так же. Похоже, что запускается только один процесс, хотя pm2
думает, что запустились все:
в pm2
-логах также видны ошибки:
$ pm2 log
...
1|npm | npm ERR! code ELIFECYCLE
1|npm | npm ERR! errno 1
1|npm | npm ERR! pm2es6@0.1.0 safestart: `node --experimental-modules src/app_es6.mjs`
1|npm | npm ERR! Exit status 1
1|npm | npm ERR!
1|npm | npm ERR! Failed at the pm2es6@0.1.0 safestart script.
1|npm | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
В "нормальном" кластере запускается указанное кол-во процессов:
alex@omen17:~/work/sof_es6_pm$ ps -Af | grep app_
alex 10903 25382 2 08:29 ? 00:00:00 node /home/alex/work/sof_es6_pm/src/app_cjs.js
alex 10910 25382 3 08:29 ? 00:00:00 node /home/alex/work/sof_es6_pm/src/app_cjs.js
alex 10919 25382 2 08:29 ? 00:00:00 node /home/alex/work/sof_es6_pm/src/app_cjs.js
alex 10932 25382 3 08:29 ? 00:00:00 node /home/alex/work/sof_es6_pm/src/app_cjs.js
Думаю, что в моём тестовом приложении идёт конкуренция за порт 3000 для express
-сервера. Какой-то из процессов первым захватывает порт, остальные отваливаются по ошибке. В логах это видно — при 4 экземплярах в кластере сообщений об ошибке только 3. pm2
каким-то образом обрабатывает вариант с портом самостоятельно, но как только мы стартуем приложение через node
/npm
, то pm2
теряет эту возможность.
Попробовал еще с модулем esm
и конфигом `ecosystem.config.js
` для PM2
:
module.exports = {
apps: [
{
name: 'PM2 Demo App',
script: './app.js',
instances: 4,
exec_mode: 'cluster',
node_args: '-r esm'
}
]
}
Логи без ошибок.
Long Term Support — это про стабильность. А модули пока ещё экспериментальные и их стабильность не гарантируется. Поэтому, в вашем случае от LTS пользы нет
Давно пользуюсь pm2. Но вот тоже думаю пора в Докер. Ибо развёртывание приложений на новые машины уже утомляет, но я и не DevOps, просто FullStackJS. Пока не было задач, где бы я мог на 100% оправдать использование Докера. Чтобы выделить время на полное изучение его workflow.А очень хочется.
От девопосов всё чаще слышу, что от разработчиков они ожидают минимум докерфайл (манифест для сборки контейнера) для включения нового сервиса или ui в систему. Типа сеньору уже не простительно не знать Докер хотя бы поверхностно, они потом оптимизируют, дотюнят, но базу им надо.
А если вы занимаетесь разворачиванием на продакшен, то вы уже девопс в современных массовых понятиях.
В некоторых случаях Docker — это просто лишний слой. Даже на проде. Если DevOps без базы не может сам засунуть приложение в контейнер, то у меня возникают вопросы уже к его квалификации. В конце концов, разрабы не обязаны знать все варианты, в которых будут гонять их приложения. Если в вашей конторе так устроено, что разрабы должны выкатывать приложения в Docker-контейнерах, то тогда — да, сеньору не простильно не знать.
Можно рассматривать базовый докерфайл и ко от разрабов как доку для девопса. Какие енв переменные приложение ожидает, какие конфиги, как его вообще собирать из исходников и как запускать. Есть и другие способы, конечно. И часть из них тоже отчасти самодокументируемые типа набора баш-скриптов, но плюс докера и подобных подходов (вагрант, например) — разработчик вынужден полностью описывать среду для своего приложения. Нет места (почти) "ой, забыл сказать, что нужно новое расширение для языка установить, я-то его ещё в первый день работы установил себе, наверное, но в проекте раньше не использовалось"
Докер это очень просто, например гораздо проще чем bash. Нужно просто понять зачем он нужен. Но вот докер на проде это уже сложно. Т.к. без средств оркестрации на проде докер предоставит больше проблем чем преимуществ. А вот средства оркестрации это уже сложнее. Например cubernetes практически невозможно развернуть и главное поддерживать в рабочем состоянии не специалисту. Поэтому приходится покупать облачный. Поэтому его пиарят нещадно. Nomad реально развернуть и поддерживать самостоятельно но мало специалистов.
Менеджер процессов, подобный pm2, является очень полезным сервисом в мире серверного JS. Но, к сожалению, сам pm2 не позволяет запускать современные nodejs-приложения (в частности — с ES6-модулями).
Я сильно не изучал этот момент, но у меня вполне получается через pm2 запускать package.json-скрипт с передачей этого флага, и все работает норм.
«scripts»: {
«start-server»: «node --experimental-modules src/server/»,
Воблер сейчас флаги практически не актуально тк последние версии нативно поддерживают модули без флагов. Проблема кроется в оператора require которым pm2 пытается инклудить основной модуль. И если в обычном режиме всякими хитростями удается все же запустить процесс, сложности начинаются когда пытаются запустить несколько процессов в режиме кластера
nodejs: менеджеры процессов и ES6-модули