Skip to content

Посты

Настройка непрерывной интеграции на Ubuntu с Node.js

15 августа 2015 г. • 10 мин чтения

Настройка непрерывной интеграции на Ubuntu с Node.js

Я прошел через кровь, пот и слезы, чтобы принести это вам. Я страдал от палящей жары Долины Смерти и покорил вершины горы Мак-Кинли. Я многим пожертвовал.

Большая часть контента, представленного в этой статье, не является моей оригинальной работой. Где возможно, я ссылаюсь на оригинальные источники.

В этой статье предполагается, что вы можете ориентироваться в Linux.

Я не смог найти комплексное руководство по размещению и управлению приложениями Node.js на Ubuntu в производственной среде. Я собрал несколько статей по этой теме. К концу этой статьи я надеюсь, что вы сможете настроить собственный сервер Ubuntu и развертывать Node.js через сервер непрерывной интеграции.

Окружение

Я использую TeamCity на Windows, который затем развертывает код из GitHub на Ubuntu, размещенный на AWS.

Технологии

Для этой статьи я использовал следующие технологии:

  • Ubuntu 14.04 на AWS
  • Plink 0.64
  • TeamCity 9.1
  • GitHub
  • Nginx 1.9.3

Настройка Ubuntu

Я не буду вдаваться в детали здесь. Amazon Web Services (AWS) делает это довольно легко. Не важно, где это находится или на вашем собственном сервере.

Я столкнулся с несколькими подводными камнями. Во-первых, убедитесь, что порт 80 открыт. Я допустил глупую ошибку, пытаясь подключиться с закрытым портом 80. Когда я обнаружил свою ошибку, я почувствовал себя ослиной задницей.

Установка Node.js из исходного кода

Node.js — это серверная технология, использующая движок JavaScript V8 от Google. С момента его выпуска в 2010 году она стала широко популярной.

Следующие инструкции первоначально взяты из поста Digital Ocean (ссылка).

У вас всегда есть возможность установить Node.js из apt-get, но это будет на несколько версий позади. Чтобы получить последние версии, установите Node.js из исходного кода.

В конце этого раздела мы загрузим последнюю стабильную версию Node (на момент написания этой статьи), построим исходный код и установим Node.js.

Войдите на ваш сервер. Начнем с обновления списков пакетов.

sudo apt-get update

Я также рекомендую обновить все пакеты. Это не обязательно для Node.js, но это хорошая практика держать ваш сервер в актуальном состоянии.

sudo apt-get upgrade

Ваш сервер полностью обновлен. Пришло время загрузить исходный код.

cd ~

На момент написания 12.7 — это последний стабильный выпуск Node.js. Посетите nodejs.org для получения последней версии.

wget https://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz

Распакуйте загруженный архив.

tar xvf node-v*

Перейдите в новый созданный каталог

cd node-v*

Настройте и соберите Node.js.

./configure

make

Установите Node.js

sudo make install

Чтобы удалить загруженные и распакованные файлы. Конечно, это необязательно.

cd ~

rm -rf node-v*

Поздравляем! Node.js теперь установлен! И это было не очень сложно.

Настройка Nginx

Источник

Node.js может действовать как веб-сервер, но это не то, что я хотел бы выставлять в мир. Промышленный, закаленный, многофункциональный веб-сервер лучше подходит для этой задачи. Я выбрал Nginx для этого.

Это зрелый веб-сервер с необходимыми нам функциями. Чтобы запустить более одного экземпляра Node.js, нам потребуется перенаправление портов.

Вы можете подумать, зачем нам нужно запускать более одного экземпляра Node.js одновременно. Это справедливый вопрос… В моем сценарии у меня есть один сервер, и мне нужно запустить DEV, QA и PROD на одной машине. Да, я знаю, что это не идеально, но я не хочу развертывать 3 сервера для каждой среды.

Для начала давайте установим Nginx

sudo -s

add-apt-repository ppa:nginx/stable

apt-get update 

apt-get install nginx

После успешной установки Nginx нам нужно настроить домены. Я предположу, что вы захотите иметь каждый из ваших сайтов на своем собственном домене/поддомене. Если нет и вы хотите использовать разные подпапки, это возможно и очень легко сделать. Я не буду рассматривать этот сценарий здесь. Есть множество документации о том, как это сделать. Очень мало документации по настройке разных доменов и перенаправлению портов на соответствующие экземпляры Node.js. Это то, что я буду рассматривать.

Теперь, когда Nginx установлен, создайте файл для yourdomain.com в /etc/nginx/sites-available/

sudo nano /etc/nginx/sites-available/yourdomain.com

Добавьте следующую конфигурацию в ваш новый файл

# the IP(s) on which your node server is running. I chose port 9001.
upstream app_myapp1 {
    server 127.0.0.1:9001;
    keepalive 8;
}

# the nginx server instance
server {
    listen 80;
    server_name yourdomain.com;
    access_log /var/log/nginx/yourdomain.log;

    # pass the request to the node.js server with the correct headers
    # and much more can be added, see nginx config options
    location / {
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://app_myapp1;

    }
 }

Убедитесь, что вы заменили “yourdomain.com” на ваш фактический домен. Сохраните и выйдите из редактора.

Создайте символическую ссылку на этот файл в каталоге sites-enabled.

cd /etc/nginx/sites-enabled/ 

ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

Чтобы проверить, что все работает правильно, создайте простое приложение Node и сохраните его в /var/www/yourdomain.com/app.js и запустите его.

Вот простое приложение Node.js, если у вас его нет под рукой.

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');}).listen(9001, "127.0.0.1");
console.log('Server running at http://127.0.0.1:9001/');

Давайте перезагрузим Nginx.

sudo /etc/init.d/nginx restart

Не забудьте запустить ваш экземпляр Node.js, если вы еще этого не сделали.

cd /var/www/yourdomain/ && node app.js

Если все работает правильно, когда вы перейдете на yourdomain.com, вы увидите “Hello World.”

Чтобы добавить еще один домен для другого экземпляра Node.js, вам нужно повторить описанные выше шаги. В частности, вам нужно будет изменить имя upstream, порт и домен в вашем новом файле конфигурации Nginx. Адрес proxy_pass должен совпадать с именем upstream в файле конфигурации nginx. Посмотрите на имя upstream и значение proxy_pass, и вы поймете, что я имею в виду.

Подводя итог, мы установили Node.js из исходного кода и только что закончили установку Nginx. Мы настроили и протестировали перенаправление портов с Nginx и Node.js

Установка PM2

Вы можете спросить “Что такое PM2?” как я, когда впервые об этом услышал. PM2 — это менеджер процессов для приложений Node.js. Node.js не поставляется с большим количеством функций. Это часть его привлекательности. Недостаток в том, что вам нужно предоставить слои перед ним. PM2 — один из этих слоев.

PM2 управляет жизненным циклом процесса Node.js. Когда он завершается, PM2 перезапускает его. Когда сервер перезагружается, PM2 перезапускает все процессы Node.js для вас. Он также имеет обширный процесс жизненного цикла разработки. Мы не будем рассматривать этот аспект PM2. Я рекомендую вам прочитать хорошо написанную документацию.

Предполагая, что вы вошли в терминал, мы начнем с установки PM2 через NPM. Npm — это менеджер пакетов Node.js (npm). Он был установлен при установке Node.js.

sudo npm install pm2 -g

Вот и все. PM2 теперь установлен.

Использование PM2

PM2 легко использовать.

Hello world для PM2 прост.

pm2 start hello.js

Это добавляет ваше приложение в список процессов PM2. Этот список выводится каждый раз при запуске приложения.

В этом примере запущены два приложения Node.js. Одно называется api.dev и api.pre.

PM2 автоматически присваивает имя приложения в список “App name”.

По умолчанию PM2 не настраивается на запуск при перезагрузке сервера. Команда отличается для разных версий Linux. Я работаю на Ubuntu, поэтому выполню команду Ubuntu.

pm2 start ubuntu

Мы еще не совсем закончили. Нам нужно добавить путь к бинарному файлу PM2. К счастью, вывод предыдущей команды говорит нам, как это сделать.

Вывод:

[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy
Run the command that was generated (similar to the highlighted output above) to set PM2 up to start on boot (use the command from your own output):

 sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u sammy

Примеры других использований PM2 (необязательно)

Остановка приложения по имени приложения

pm2 stop example

Перезагрузка по имени приложения

pm2 restart example

Список текущих приложений, управляемых PM2

pm2 list

Указание имени при запуске процесса. Если вы вызовете, PM2 использует файл javascript в качестве имени. Это может не сработать для вас. Вот как указать имя.

pm2 start www.js --name api.pre

Этого должно быть достаточно, чтобы начать работу с PM2. Чтобы узнать больше о возможностях PM2, посетите GitHub Repo.

Вы, вероятно, думаете: “Что во имя Бетси это такое Plink?” По крайней мере, это то, что я думал. Я все еще не уверен, что об этом думать. Я никогда не видел ничего подобного.

Вы когда-нибудь смотрели фильм Wall-e? Wall-e вытаскивает ложку-вилку. Сначала он пытается положить ее с вилками, но она не подходит, а затем пытается положить ее с ложками, но она тоже не подходит. Вот такой Plink. Это нечто среднее между Putty (SSH) и командной строкой Windows.

Plink в основном позволяет вам запускать команды bash из командной строки Windows, находясь в оболочке Linux (и, вероятно, Unix).

Начните с загрузки Plink. Это просто исполняемый файл. Я рекомендую поместить его в C:/Program Files (x86)/Plink. Нам нужно будет ссылаться на него позже.

Если вы запускаете экземпляр Ubuntu в AWS, у вас уже должен быть сертификат, установленный для Putty (я предполагаю, что вы используете Putty).

Если нет, вам нужно убедиться, что у вас есть совместимый сертификат ssh для Ubuntu в AWS.

Если вы не используете AWS, вы можете указать имя пользователя и пароль в командной строке и не беспокоиться о сертификатах ssh.

Вот пример команды, которая подключается к Ubuntu с помощью Plink.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" 

Это может быть забегание вперед, но чтобы запустить ssh-скрипт на сервере Ubuntu, мы добавляем полный путь в конец команды Plink.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-dev-ui.sh

И вот, дорогой читатель, это Plink.

Понимание NODE_ENV

NODE_ENV — это переменная окружения, популяризированная expressjs. Перед запуском экземпляра Node установите NODE_ENV на окружение. В коде вы можете загружать определенные файлы в зависимости от окружения.

Setting NODE_ENV
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD

Переменная окружения извлекается внутри экземпляра Node.js с помощью process.env.NODE_ENV.

пример

var environment = process.env.NODE_ENV

или с expressjs

app.get('env')

*Примечание: app.get('env') по умолчанию имеет значение “development”.

Объединение всего вместе

Node.js, PM2, Nginx и Plink установлены и, надеюсь, работают. Теперь нам нужно объединить все эти части в решение непрерывной интеграции.

Клонируйте ваш репозиторий GitHub в /var/www/yourdomain.com. Хотя SSH более безопасен, чем HTTPS, я рекомендую использовать HTTPS. Я знаю, что это не идеально, но я не смог заставить Plink работать с GitHub на Ubuntu. Без вдаления в детали, форматы сертификатов SSH Plink и GitHub различаются, и вызов GitHub через Plink через SSH не сработал. Если вы сможете разобраться с проблемой, дайте мне знать!

Чтобы сделать загрузку из GitHub автоматической, имя пользователя и пароль должны быть частью URL-адреса origin.

Вот как вы устанавливаете URL-адрес origin. Конечно, вам нужно будет подставить вашу информацию где это необходимо.

git remote set-url origin  https://username:password@github.com/username/yourdomain.git

Клонируйте ваш репозиторий.

cd /var/www/yourdomain.com
git clone https://username:password@github.com/username/yourdomain.git .

Обратите внимание, что если этот каталог не полностью пуст, включая скрытые файлы, Git не будет клонировать репозиторий в этот каталог.

Чтобы найти скрытые файлы в каталоге, выполните эту команду

ls -a

Для связывания мы используем shell-скрипт. Вот копия моего скрипта.

#!/bin/bash

echo "> Current PM2 Apps"
pm2 list

echo "> Stopping running API"
pm2 stop api.dev

echo "> Set Environment variable."
export NODE_ENV=DEV

echo "> Changing directory to dev.momentz.com."
cd /var/www/yourdomain.com

echo "> Listing the contents of the directory."
ls -a

echo "> Remove untracked directories in addition to untracked files."
git clean -f -d

echo "> Pull updates from Github."
git pull

echo "> Install npm updates."
sudo npm install

echo "> Transpile the ECMAScript 2015 code"
gulp babel

echo "> Restart the API"
pm2 start transpiled/www.js --name api.dev

echo "> List folder directories"
ls -a

echo "> All done."

Я запускаю этот shell-скрипт с помощью TeamCity, но вы можете запустить его с помощью чего угодно.

Вот необработанная команда.

"C:\Program Files (x86)\Plink\plink.exe" -ssh ubuntu@xx.xx.xx.xx -i "C:\Program Files (x86)\Plink\ssh certs\aws-ubuntu.ppk" /var/www/deploy-yourdomain.sh
exit
>&2

Вот и все.

В заключение

Этот процесс имеет некоторые шероховатости… Я надеюсь отполировать эти края со временем. Если у вас есть предложения, пожалуйста, оставьте их в комментариях.

Этот документ находится в моем GitHub Repository. Технологии меняются, поэтому если вы найдете ошибку, пожалуйста, обновите ее. Я затем обновлю этот пост.

Автор: Chuck Conway — инженер AI с почти 30-летним опытом разработки программного обеспечения. Он создает практические системы AI — конвейеры контента, агенты инфраструктуры и инструменты, которые решают реальные проблемы — и делится тем, что он узнает на этом пути. Свяжитесь с ним в социальных сетях: X (@chuckconway) или посетите его на YouTube и на SubStack.

↑ Вернуться в начало

Вам также может понравиться