Skip to content

Посты

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

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

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

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

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

Эта статья предполагает, что вы умеете работать с Linux.

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

Окружение

Я использую 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. Когда я обнаружил свою ошибку, я почувствовал себя как задница носорога.

Установка Nodejs из исходного кода

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

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

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

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

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

sudo apt-get update

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

sudo apt-get upgrade

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

cd ~

На момент написания 12.7 является последним стабильным релизом Nodejs. Проверьте nodejs.org для получения последней версии.

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

Извлеките загруженный архив.

tar xvf node-v*

Перейдите в только что созданную директорию

cd node-v*

Настройте и соберите Nodejs.

./configure

make

Установите Nodejs

sudo make install

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

cd ~

rm -rf node-v*

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

Настройка Nginx

Источник

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

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

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

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

sudo -s

add-apt-repository ppa:nginx/stable

apt-get update 

apt-get install nginx

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

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

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

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

# IP-адрес(а), на которых работает ваш node сервер. Я выбрал порт 9001.
upstream app_myapp1 {
    server 127.0.0.1:9001;
    keepalive 8;
}

# экземпляр nginx сервера
server {
    listen 80;
    server_name yourdomain.com;
    access_log /var/log/nginx/yourdomain.log;

    # передача запроса на node.js сервер с правильными заголовками
    # и многое другое может быть добавлено, см. опции конфигурации nginx
    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 и запустите его.

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

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

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

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

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

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

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

Установка PM2

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

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

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

sudo npm install pm2 -g

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

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

PM2 прост в использовании.

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

pm2 start hello.js

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

В этом примере работают два приложения Nodejs. Одно называется 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 в окружение. В коде вы можете загружать определенные файлы на основе окружения.

Установка NODE_ENV
Linux & Mac: export NODE_ENV=PROD
Windows: set NODE_ENV=PROD

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

пример

var environment = process.env.NODE_ENV

или с expressjs

app.get('env')

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

Объединяем все вместе

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

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

Чтобы сделать GitHub pull автоматическим, имя пользователя и пароль должны быть частью 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. Технологии меняются, поэтому если вы найдете ошибку, пожалуйста, обновите ее. Затем я обновлю этот пост.

Автор: Чак Конвей специализируется на разработке программного обеспечения и генеративном ИИ. Свяжитесь с ним в социальных сетях: X (@chuckconway) или посетите его на YouTube.

↑ Наверх

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