Deploy проекта на Node.js

Всем привет!

Вопрос такой: какой правильный нынче путь для deploy’я и запуска Node.js проекта на хостинге (Linux)?

Насколько я знаю, по канонам continuous integration это должна быть связка:

  1. Репозитория с кодом (git, bitbucket e.t.c.)
  2. Штуковина для building, deploying and automating any project ( jenkins )
  3. Демон ( pm2 )
  4. Штуковина для мониторинга ( zabbix )

Но стоит ли с этим заморачиваться, если проект 2 api’шки - 3 страницы?
Можно ли обойтись одним pm2 для начала?
Если pm2 “смотрит” за проектом и перезапускает его когда что-то идёт не так, то кто перезапустит сам pm2, когда будут какие-то проблемы на самом хостинге?

Да, я бы рекомендовал именно так. Позже докрутить дженксинс и дополнительный мониторинг не составит труда.

Для маленького проекта я сделал такой сетап:

  1. Настроил гит репозиторий на самой машине куда деплою.
  2. Настроил pm2 так чтобы он деплоил из этого репозитория.

Деплой выглядит так:

  1. Пушу код. Код уходит в репозиторий на деплой машине
  2. Запускаю со своей машины pm2 deploy ecosystem.config.js production --env production. Эта команда говорит удаленному pm2 сходить за кодом в локальный для pm2 репозиторий (на той же машине), и задеплоить код.

Если речь о рестарте твоего приложения после рестарта системы, то никаких дополнительных мониторов для этого не надо. Главное - пройди шаги настройки pm2 на сервере. PM2 - Startup Script

Супер, спасибо! А БД как мигрировать при этом?

Про БД подсказать из опыта не могу. Если бы решал задачу, то попробовал бы взять готовое решение для миграции БД, и встроить его в процесс старта приложения (вызов прямо в коде приложения). http://pm2.keymetrics.io/docs/usage/signals-clean-restart/

Для приложения в две апишки миграции бы не автоматизировал. Разве что ради развлечения.

Не получается что-то у меня deploy.
Репозиторий на bitbucket.org, публичный ключ туда и себе локально я добавил.
Запускаю локально:

pm2 deploy ecosystem.config.js production setup

А мне в ответ:

--> Deploying to production environment
--> on host [host]
  ○ hook pre-setup
  ○ running setup
  ○ cloning git@bitbucket.org:[user]/[project].git
warning: templates not found /usr/share/git-core/templates
Cloning into '/home/[user]/public_html/source'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

  failed to clone

Deploy failed

Создал по примеру ~/.ssh/config, но результат тот же.

Host alias
    HostName [site_host_name]
    User [local_user]
    IdentityFile ~/.ssh/id_rsa

Host deployment
    HostName bitbucket.org
    User [bitbucket_user]
    IdentityFile ~/.ssh/id_rsa.pub

Я не уловил: деплоишь на какой хост? На локальную машину? Если ты деплоишь на удаленную, то публичный ключ от битбакета должен быть на удаленной машине.

Деплою на удаленный хост. Не совсем понял что такое “публичный ключ от битбакета”. Я сгенерил на хостинге ключи и прописал публичный в bitbucket. На самом bitbucket никакого генератора ключей я не нашел.

Всё заработало, когда я дописал в ecosystem.config.js:

"forward-agent": "yes",

Но теперь возникла другая проблема: про выполнении команды деплоя pm2 берёт commit 3-х часовой давности.

pm2 deploy ecosystem.config.js production --env production update не помогает. Что это может быть?

Эта штука позволила в схеме Ты → server → bitbucket использовать server-ом к bitbucket ssh ключ, который хравнится на твоей машине. Тут подробнее Using SSH agent forwarding - GitHub Docs

pm2 деплоит из удаленного репозитория. Ты пушнул коммиты, которые ожидаешь увидеть после деплоя?

Но ведь ключи на моей локальной и удаленной машине одинаковые. Странно, почему не заработали удаленные ключи.

Да, конечно. Я тут нарыл, что это может быть связано с проблемой самого git. На хостинге как раз стоит версия < 1.9, после которой эта проблема вроде бы решается.

[…] Спустя год работы проекта в таком виде, как описан ранее в данной теме, я пришел к выводу, что такой подход к deploy не совсем удачен.

Что происходит сейчас:

  1. Написал код и залил в репозиторий.
  2. Запустил локально команду для deploy ( npm run deploy ), которая под капотом запускает pm2 deploy ecosystem.config.js.
  3. pm2 на сервере идет в git и забирает последние изменения.
  4. На сервере запускается сборщик проекта ( gulp ) и создает /dist с готовыми для production файлами.
  5. pm2 перезапускает приложение.

Что мне не нравится:

  1. Директория /.git на production: небезопасно. Плюс для корректной работы такого flow, нужно настраивать ssh-ключи на сервере.
  2. Production сервер занимается тем, о чём знать не должен: ходит в репозиторий и собирает проект.

По-хорошему, в этой цепочке должен быть stage-сервер, который делает всю подготовительную работу (всё то, что сейчас делает у меня production) и заливать только /dist на production-сервер. Т.к. stage у меня нет (и не предвидится т.к. проект не настолько большой, чтобы с этим заморачиваться), то я хотел бы подготовительный работы делать локально.

Что я хочу:

  1. Написал код и залил в репозиторий.
  2. Запустил локально сборщик проекта и получил /dist.
  3. Заархивировал собранные файлы.
  4. Отправил на сервер (подойдёт ли для этого Linux-команда scp?).
  5. На сервере распаковал и перезапустил проект.

Вопросы:

  1. Впишется ли это во deploy flow pm2? Какие подводные камни могут вылезти?
  2. Будет ли возможность управлять версиями deploy (откатывать на предыдущие)?
  3. Заливать нужно в папку /source?

Буду искренне благодарен, если кто-то сталкивался с подобным и знает best practices.