Развёртывание приложения Meteor.js на Nginx в Ubuntu 14.04

Meteor.js – это фреймворк для JavaScript, позволяющий разработчикам использовать написанный код как на серверной, так и на клиентской стороне.

Примечание: Подробнее об особенностях сборки в Meteor.js можно узнать здесь.

Meteor.js также устраняет необходимость сложного процесса развертывания между режимом разработки (когда разработчик пишет код и устраняет неполадки) и режимом производства (в котором код уже является безопасным и общедоступным приложением). Фреймворк Meteor.js  позволяет тесно связать клиентский и серверный код, а также среду разработки и производства. Это, пожалуй, самый простой способ для разработчиков клиентской стороны начать работать на стороне сервера кода.

Примечание: На сайте Meteor можно найти ознакомительное видео.

Meteor.js позволяет разрабатывать веб-сайты (веб-приложения), браузерные приложения на основе HTML5 (при помощи AppCache) и мобильные приложения (интегрируясь с PhoneGap). Для работы с этим фреймворком нужны знания Javascript и HTML. Также Meteor поддерживает MongoDB. На сайте Atmosphere можно найти целые блоки для сборки приложения.

Данное руководство поможет:

  • Установить Meteor.js
  • Установить веб-сервер Nginx
  • Установить MongoDB
  • Настроить управление приложением при помощи скрипта Upstart
  • Настроить ежедневное резервное копирование БД.

Если у вас ещё нет приложения, написанного в Meteor.js, можно использовать образец приложения Todo List с сайта проекта.

Требования

  • Подготовленное приложение Meteor на сервере разработки (например, приложениеTodo List).
  • Сервер Ubuntu 14.04.
  • Доступ root.
  • Обновите индекс пакетов:

apt-get update

  • Замените todos.net своим доменным именем; если доменного имени нет, ничего не меняйте.
  • Замените имя тестового приложения (todos) именем своего приложения.

1: Установка и настройка Nginx

Nginx позволяет шифровать трафик при помощи SSL, встроенный веб-сервер Meteor не предоставляет такой функции. Nginx также позволяет обслуживать несколько сайтов на одном и том же сервере и фильтровать логи. Ниже показано, как защитить сайт при помощи сертификата SSL и перенаправить весь трафик с HTTP на HTTPS.

Чтобы установить Nginx:

apt-get install nginx

Создайте конфигурационный файл виртуального хоста в /etc/nginx/sites-available.

Поместите в этот файл (/etc/nginx/sites-available/todos) предложенный ниже код.

server_tokens off; # for security-by-obscurity: stop displaying nginx version
# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
default upgrade;
''      close;
}
# HTTP
server {
listen 80 default_server; # if this is not a default server, remove "default_server"
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html; # root is irrelevant
index index.html index.htm; # this is also irrelevant
server_name todos.net; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.
# redirect non-SSL to SSL
location / {
rewrite     ^ https://$server_name$request_uri? permanent;
}
}
# HTTPS server
server {
listen 443 ssl spdy; # we enable SPDY here
server_name todos.net; # this domain must match Common Name (CN) in the SSL certificate
root html; # irrelevant
index index.html; # irrelevant
ssl_certificate /etc/nginx/ssl/todos.pem; # full path to SSL certificate and CA certificate concatenated together
ssl_certificate_key /etc/nginx/ssl/todos.key; # full path to SSL key
# performance enhancement for SSL
ssl_stapling on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
# safety enhancement to SSL: make sure we actually use a safe cipher
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
add_header Strict-Transport-Security "max-age=31536000;";
# If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
# This works because IE 11 does not present itself as MSIE anymore
if ($http_user_agent ~ "MSIE" ) {
return 303 https://browser-update.org/update.html;
}
# pass all requests to Meteor
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
# this setting allows the browser to cache the application in a way compatible with Meteor
# on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
# the root path (/) MUST NOT be cached
if ($uri != '/') {
expires 30d;
}
}
}

Можно изменить конфигурации в файле согласно требованиям приложения.

Примечание: Чтобы узнать больше о виртуальных хостах Nginx, читайте статью «Nginx: Настройка блоков server».

Согласно конфигурациям, Nginx будет искать валидный SSL-сертификат и ключ в каталоге /etc/nginx/ssl. Создайте такой каталог и ограничьте доступ к нему:

mkdir /etc/nginx/ssl
chmod 0700 /etc/nginx/ssl

Затем создайте файлы сертификата и ключа (/etc/nginx/ssl/todos.pem и /etc/nginx/ssl/todos.key соответственно).

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

Примечание: Самоподписанный сертификат подходит для целей тестирования, но в производстве рекомендуется использовать сертификат, заверенный надёжным ЦС.

Получив сертификат, отключите стандартный виртуальный хост.

rm /etc/nginx/sites-enabled/default

Включите только что созданный виртуальных хост для Meteor:

ln -s /etc/nginx/sites-available/todos /etc/nginx/sites-enabled/todos

Убедитесь, что настройки виртуального хоста не содержат ошибок:

nginx -t

Примечание: Если вы используете самоподписанный сертификат, сервер сообщит об ошибке ssl_stapling.

Если ошибок не обнаружено, обновите настройки Nginx:

nginx -s reload

Теперь можно открыть приложение в браузере; оно доступно по ссылке https://todos.net (если у вас нет домена, замените его своим IP-адресом). Браузерр выдаст ошибку 502 Bad Gateway; это нормальное поведение, поскольку фреймворк Meteor ещё не запущен.

2: Установка и настройка MongoDB

Установите MongoDB из стандартного репозитория Ubuntu. Стандартные настройки СУБД вполне подойдут для поддержки тестового приложения. СУБД не запрашивает учётных данных пользователя, но соединения возможны только с локального хоста, то есть любые внешние соединения запрещены, следовательно, база данных находится в безопасности (если в системе нет ненадежных пользователей с доступ SSH).

Установите MongoDB:

apt-get install mongodb-server

Система MongoDB готова к работе. Чтобы убедиться в том, что внешний доступ к БД заблокирован, узнайте, привязана ли БД MongoDB к 127.0.0.1:

netstat -ln | grep -E '27017|28017'

Команда должна вернуть:

tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN
unix  2      [ ACC ]     STREAM     LISTENING     6091441  /tmp/mongodb-27017.sock

Чтобы настроить поддержку ежедневного резервного копирования, можно установить простую команду daily для cron job (опционально). Создайте файл /etc/cron.d/mongodb-backup:

@daily root mkdir -p /var/backups/mongodb; mongodump --db todos --out /var/backups/mongodb/$(date +'\%Y-\%m-\%d')

3: Установка приложения Meteor

Сначала нужно установить Node.js. Как правило, версии Node.js в стандартных репозиториях системы устаревшие и не могут обеспечить корректной работы Meteor. Для этого необходимы более новые версии Node.js. Получить такую версию можно в репозитории PPA.

Чтобы добавить репозиторий PPA с программой Node.js, введите:

add-apt-repository ppa:chris-lea/node.js

Команда вернёт:

Evented I/O for V8 javascript. Node's goal is to provide an easy way to build scalable network programs
More info: https://launchpad.net/~chris-lea/+archive/ubuntu/node.js
Press [ENTER] to continue or ctrl-c to cancel adding it
gpg: keyring `/tmp/tmphsbizg3u/secring.gpg' created
gpg: keyring `/tmp/tmphsbizg3u/pubring.gpg' created
gpg: requesting key C7917B12 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmphsbizg3u/trustdb.gpg: trustdb created
gpg: key C7917B12: public key "Launchpad chrislea" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

Обновите кэш репозиториев и установите Node.js and npm (пакетный менеджер):

apt-get update
apt-get install nodejs

Теперь нужно создать системного пользователя для запуска Meteor.

adduser --disabled-login todos

Команда должна вернуть:

Adding user `todos' ...
Adding new group `todos' (1001) ...
Adding new user `todos' (1001) with group `todos' ...
Creating home directory `/home/todos' ...
Copying files from `/etc/skel' ...
Changing the user information for todos
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]

4: Создание скрипта Upstart

Теперь нужно создать скрипт Upstart для управления приложением. Такой скрипт обеспечивает автоматическую загрузку приложения во время запуска системы и перезапуск приложения в случае сбоя.

Создайте файл /etc/init/todos.conf. Вставьте в него код:

# upstart service file at /etc/init/todos.conf
description "Meteor.js (NodeJS) application"
author "Daniel Speichert <daniel@speichert.pro>"
# When to start the service
start on started mongodb and runlevel [2345] # When to stop the service
stop on shutdown
# Automatically restart process if crashed
respawn
respawn limit 10 5
# we don't use buil-in log because we use a script below
# console log
# drop root proviliges and switch to mymetorapp user
setuid todos
setgid todos
script
export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
# set to home directory of the user Meteor will be running as
export PWD=/home/todos
export HOME=/home/todos
# leave as 127.0.0.1 for security
export BIND_IP=127.0.0.1
# the port nginx is proxying requests to
export PORT=8080
# this allows Meteor to figure out correct IP address of visitors
export HTTP_FORWARDED_COUNT=1
# MongoDB connection string using todos as database name
export MONGO_URL=mongodb://localhost:27017/todos
# The domain name as configured previously as server_name in nginx
export ROOT_URL=https://todos.net
# optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
export METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
# this is optional: http://docs.meteor.com/#email
# commented out will default to no email being sent
# you must register with MailGun to have a username and password there
# export MAIL_URL=smtp://postmaster@mymetorapp.net:password123@smtp.mailgun.org
# alternatively install "apt-get install default-mta" and uncomment:
# export MAIL_URL=smtp://localhost
exec node /home/todos/bundle/main.js >> /home/todos/todos.log
end script

Одним из важнейших параметров этого скрипта является METEOR_SETTINGS. Если вы используете meteor –settings config.json при запуске режима разработки Meteor, то вы должны также добавить в скрипт содержимое файла config.json в качестве значения переменной METEOR_SETTINGS.

В переменной MAIL_URL нужно указать валидный SMTP URL только в том случае, если вы планируете использовать пакет электронной почты Meteor. Можно, к примеру, установить MailGun (рекомендуется командой Meteor).

Согласно параметрам, лог будет находиться в /home/todos/todos.log. Этот файл не ротируется и со временем может значительно увеличиться в размерах. Потому важно не переполнять его сообщениями об ошибках. Опционально можно настроить ротацию этого лога; также можно заменить >> на > в конце скрипта Upstart, и тогда система каждый раз будет переписывать лог сначала, а не добавлять новые записи в конец файла.

5: Развёртывание приложения Meteor

Если у вас нет готового приложения, Meteor предоставляет тестовые приложения.

Чтобы получить такое приложение, сначала нужно открыть домашний каталог:

cd ~

Затем – установить версию разработки Meteor:

curl https://install.meteor.com | /bin/sh

Далее нужно создать тестовое приложение под названием Todo List.

meteor create --example todos

Готово! Теперь откройте каталог приложения:

cd todos

Проекты Meteor

Приступайте к созданию связок для производства.

Примечание: Все команды нужно выполнить на машине, которая хранит приложение Meteor; это может быть домашний компьютер или сервер разработки.

Откройте каталог проекта:

cd /app/dir

Выполните:

meteor build .

Эта команда создаст файл todos.tar.gz в каталоге /app/dir. Скопируйте этот файл в домашний каталог сервера.

scp todos.tar.gz root@todos.net:~

Перейдите на сервер. Создайте каталог проекта и переместите в него скопированный архив. Этот каталог должен быть домашним каталогом системного пользователя, созданного для запуска приложения (не домашний каталог root).

mkdir /home/todos
mv todos.tar.gz /home/todos

Откройте каталог проекта и распакуйте архив:

cd /home/todos
tar -zxf todos.tar.gz

Просмотрите README проекта:

cat /home/todos/bundle/README
This is a Meteor application bundle. It has only one external dependency:
Node.js 0.10.29 or newer. To run the application:
$ (cd programs/server && npm install)
$ export MONGO_URL='mongodb://user:password@host:port/databasename'
$ export ROOT_URL='http://example.com'
$ export MAIL_URL='smtp://user:password@mailhost:port/'
$ node main.js
Use the PORT environment variable to set the port where the
application will listen. The default is 80, but that will require
root on most systems.
Find out more about Meteor at meteor.com.

Этот код повторяется в файле /etc/init/todos.conf.
Теперь нужно установить модули npm. Чтобы собрать некоторые из них, нужно установить g++ и make.

apt-get install g++ make
cd /home/todos/bundle/programs/server

Команда вернёт:

npm WARN package.json meteor-dev-bundle@0.0.0 No description
npm WARN package.json meteor-dev-bundle@0.0.0 No repository field.
npm WARN package.json meteor-dev-bundle@0.0.0 No README data
> fibers@1.0.1 install /home/todos/bundle/programs/server/node_modules/fibers
> node ./build.js
`linux-x64-v8-3.14` exists; testing
Binary is fine; exiting
underscore@1.5.2 node_modules/underscore
semver@2.2.1 node_modules/semver
source-map-support@0.2.5 node_modules/source-map-support
└── source-map@0.1.29 (amdefine@0.1.0)
fibers@1.0.1 node_modules/fibers

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

Приложение почти готово к запуску. Однако обратите внимание: все операции в файлах были выполнены от пользователя root, но они должны принадлежать пользователю todos. Передайте права на файлы:

chown todos:todos /home/todos -R

6: Запуск приложения

Чтобы запустить приложение, выполните команду в каталоге проекта:

start todos

Теперь приложение доступно по ссылке:

https://todos.net

Повторное развёртывание приложения

Внеся изменения в приложение в режиме разработки, повторите раздел 5 (с команды meteor build и до restart todos, которая перезапустит приложение через Upstart).

Это обновит приложение без простоя. Все клиенты приложения (посетители сайта) автоматически получат новую версию кода при обновлении страницы.

Вы можете протестировать это поведение. Для этого внесите небольшое изменение в код страницы todos/client/todos.html в режиме разработки.

На сервере разработки:

Соберите:

meteor build /app/dir

Загрузите:

scp todos.tar.gz root@todos.net:/home/todos

На сервере производства:

Распакуйте:

tar -zxf /home/todos/todos.tar.gz

Перейдите в каталог проекта:

cd /home/todos/bundle/programs/server

Обновите модули npm (программа может вернуть несколько предупреждений):

npm install

Перезапустите приложение:

restart todos

Устранение неполадок

В случае возникновения ошибок или сбоев проверьте:

  • Лог /home/todos/todos.log, если приложение запускается, но сразу останавливается.
  • /var/log/nginx/error.log, если приложение не открывается и возвращает ошибку HTTP.
  • var/log/mongodb/mongodb.log, если ошибки возникли в Базе данных.

Убедитесь, что все сервисы запущены:

status todos
service nginx status
status mongodb

Tags: , , , ,

Добавить комментарий