По ходу изучения Node.js я создал много маленьких проектов. В дальнейшем мне понадобилось развернуть некоторые из них на сервере, чтобы иметь возможность развивать их в дальнейшем. Существующие хостинги Appfog и Heroku имеют ряд серьезных ограничений на бесплатных аккаунтах. На Appfog'е можно запускать одновременно не больше 2-х приложений, и бесплатная регистрация у них уже отключена. На Heroku можно создать только 5 приложений (без базы данных) без подтверждения аккаунта привязкой банковской карты. Платные аккаунты стоят очень дорого для меня (я ведь не зарабатываю на этих маленьких проектах): $20 долларов на Appfog, а heroku еще дороже. Коллеги порекомендовали попробовать хостинг на Digital Ocean — виртуальный сервер за $5 доларов в месяц, на котором можно легко настроить собственный хостинг node.js-проектов.
О том, как организовать такой хостинг, и будет идти речь в этой статье. Если по ходу руководства у вас возникнут проблемы, поищите их решение в конце статьи.
Создаем VPS
1. Регистрация на DigitalOcean
Первым делом регистрируемся на сайте DigitalOcean. Здесь мы купим VPS — виртуальный сервер. После удачной регистрации и входа в свою админку жмем на большую зеленую кнопку "Create" и нам предложат активировать свой аккаунт, внеся $5 долларов. Ниже на странице есть место для указания счастливого купона на $10, вводите OMGSSD10 или поищите свежий купон. Так как моя банковская карточка не подошла хостеру, я оплатил пейпалом и у меня на счету оказалось $15. Этого должно хватить на 3 месяца.
2. Создаем SSH-ключ
Доступ к удаленным серверам обычно делается по ssh. Это такая технология защищенных соединений. Зайти в нашу будущую VPS можно по паролю или по SSH-ключу. Я настоятельно рекомендую второй вариант, не придется все время вводить пароль. Также, SSH-ключ все равно нужно будет указать при создании нашего нового "дроплета" (словом "droplet" DigitalOcean называет виртуальный сервер).
Выполните следующие две команды в терминале, чтобы сгенерировать ssh-ключ:
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "email@example.com"
И тут нас просят ввести имя файла ключа. Рекомендую использовать что-нибудь вроде id_rsa_digitalocean_dropletname, где имя дроплета — это либо имя домена, на который мы привяжем наш сервер, либо просто какое-нибудь осмысленное название. Парафразу можно оставить пустой, и так сойдет.
После этого будет создано два файла: ssh-ключ и public-ключ. Скопируем публичный ключ в буфер обмена модным способом:
Теперь зайдем в админку в digitaloceans в раздел SSH-keys и создадим там новый ключ, вставив его из буфера обмена.
3. Создаем дроплет
Теперь настало время купить виртуальный сервер. Нажимаем на большую зеленую кнопку «Create» и вводим следующую информацию:
В качестве hostname укажите доменное имя или что-нибудь осмысленное, это название роли не играет
Размер выбирайте самый маленький, его потом можно будет увеличить из терминала
Регион любой, я выбрал Амстердам
Образ выберите на вкладке Applications, c названием "Dokku v0.2.3 on Ubuntu..." или похожим
Укажите SSH-ключ, который мы создали на предыдущем шаге
Жмем "Create Droplet" и ждем 2-10 минут. В результате мы увидим панель управления дроплетом, и там будет виден его IP-адрес.
Выбранный образ помимо операционной системы Ubuntu 14.04 содержит самое главное: Dokku. Это готовая система для хостинга node.js-проектов, очень похожая на Heroku. Использование образа с предустановленным Dokku избавит нас от необходимости устанавливать и настраивать систему для хостинга Node.js.
4. Настройка Дроплета и DNS
Теперь нужно настроить новосозданный сервер. Зайдите в браузере по IP-адресу дроплета и вы увидете экран настройки. Если такой страницы нет, смотрите что делать в конце статьи.
Здесь вы должны убедится, что поле "Public Key" заполнено. Если нет — укажите свой public key из недавно сгенерированного ключа. Однако практика показала, что лучше вообще удалить такой дроплет и создать новый, правильно указав SSH-ключ.
Если у вас нет доменного имени, то оставьте все, как есть, жмите "Finish setup" и переходите к следующему пункту. Ваше приложение будет доступно примерно так: "19.19.197.19:46667", по IP адресу и номеру порта. Если вас это не устраивает — срочно купите доменное имя. В любом случае, настроить доменное имя можно будет позже, о чем я расскажу в конце.
Если вы укажете доменное имя, у вас будет возможность настроить доступ к приложениям через поддомены. Например, если ваше доменное имя mydomain.com, тогда ваше приложение будет доступно по адресу app.mydomain.com. Также есть возможность привязать приложение на главный домен, но об это я в данной статье не расскажу.
Укажите в поле Hostname ваше доменное имя и поставьте галочку "Use virtualhost naming for apps". Теперь идите в панель управления вашим доменным именем и впишите две новые настройки примерно так:
apps.mydomain.com. IN A [Droplet IP address]
*.apps.mydomain.com. IN A [Droplet IP address]
Или так:
mydomain.com. IN A [Droplet IP address]
*.mydomain.com. IN A [Droplet IP address]
Точный синтаксис уточните у себя в админке доменного имени или у домен-провайдера.
Теперь возвращайтесь на страницу настройки дроплета и жмите "Finish setup".
5. Настраиваем использование SSH
Давайте попробуем соединиться с нашим новым сервером. Чтобы получить доступ дроплету через SSH-ключ, нужно еще одно маленькое действие. Откройте терминал и передите в папку с ssh-ключами:
$ cd ~/.ssh/
Если у вас еще нет файла "config" в этой папке (проверка — $ ls), то его необходимо создать:
$ touch config
Теперь открываем config($ open config) и записываем в него следующие данные:
Где в первой строчке IP адрес или доменное имя, на второй строчке — имя созданного ssh-ключа для этого дроплета.
Проверяем соединение:
$ ssh root@YOUR.DROPLET.IP.ADDRESS
Где после "@" надо указать или доменное имя, или IP.
Если вы пропустили создание SSH-ключа, войти можно по паролю, который пришел к вам на почту. Для этого выполните ту же команду:
$ ssh root@YOUR.DROPLET.IP.ADDRESS
и на вопрос о продолжении соединения напишите "yes". После этого введите пароль.
Если вы увидели приветственный экран, значит все хорошо. Закроем соединение командой exit и перейдем к следующему пункту.
Деплоим приложение
Сервер готов, теперь пришла очередь развернуть тестовое приложение и проверить его работу.
1. Подготавливаем проект
Возьмите простой проект, типа Hello, world, без mongodb и прочего. Проверьте, что в проекте есть самое главное: "package.json", "Procfile" и какой-нибудь "app.js". "Package.json" должен выглядеть примерно так:
Если у нас было доменное имя для дроплета, то пишем его после "dokku@", иначе — указываем IP. После двоеточия мы указываем имя приложения. Этот индификатор будет использоваться внутри dokku.
Теперь вызываем команду push:
$ git push dokku master
И начинается загрузка приложения, установка модулей. В конце на экране покажется url, по которому можно запустить проект. Это будет ссылка вида 192.88.67.168:46567 или app1.mydomain.com, в зависимости от настроек dokku.
По идее проект должен быть запущен после этого. Но если нет, то заходим в по ssh в наш дроплет и выполняем две команды
$ cd /home/dokku/YOUR-APP-NAME
$ dokku run YOUR-APP-NAME node app.js
Запускаем в браузере ссылку, полученную ранее, и радуемся!
Проблемы и их устранение
Я сам разбирался с настройкой такого хостинга более суток, и набил несколько шишек. И чтобы вы могли съэкономить свое время, привожу здесь несколько возможных проблем и пути их решения.
1. Мою банковскую карточку не приняли для оплаты
Они такие, да. Даже Visa Classic им не нравится. Оплатите через PayPal, это не трудно.
2. Создал дроплет, но по IP адресу нет страницы настройки dokku
Значит, у DigitalOcean что-то пошло не так. Надо зайти на страницу управления дроплетом, и на вкладке Destroy/Rebuild:
указать образ с Dokku
нажмите кнопку "Rebuild from Image".
Тогда, после перестройки, страница настройки dokku должна быть видна по IP-адресу. Если нет — попросите помощи у DigitalOcean.
3. Не могу получить доступ к дроплету ни по паролю, ни по SSH
Наверное, вы как-то пропустили шаг настройки dokku, или dokky создался не правильно.
Проверьте, если доступна страница настройки dokku по IP адресу дроплета, то вернитесь к шагу 4 создания VPS.
Если страницы настроек нет, тогда попробуйте сбросить пароль и повторить попытку доступа через терминал. Если даже в этом случае доступ по паролю будет неудачным, тогда переустановите дроплет, как описано в предыдущем пункте.
4. Я не знаю пароля от дроплета
Если у вас нет пароля, зайдите на страницу управления дроплетом, вкладка "Access" и сделайте reset пароля. Тогда на почту придет новый пароль.
5. Проект не запускается по указанной ссылке
Если настройки dokku верны, такая ситуация возможна, если приложение запустилось с ошибкой и было закрыто. Зайтиде по ssh в дроплет и проверьте логи:
$ dokku logs <app_name>
Возможно, ошибка будет понятна. Или же вы забыли запустить ваш проект после push'а:
$ cd /home/dokku/YOUR-APP-NAME
$ dokku run YOUR-APP-NAME node app.js
6. Я пропустил создание SSH, и теперь хочу сделать авторизацию по SSH-ключу
Я пытался создать новый дроплет без указания ssh-ключа на странице создания дроплета, но на странице настроек dokku все равно просят ввести паблик-ключ. После этого я принял некоторые действия, но все равно зайти по ssh-ключу у меня не вышло, только пароль. Так что я не знаю, как лучше действовать в данной ситуации. Возможно, ошибка происходила при команде копирования ssh ключа в дроплет. Гуглите. В крайнем случае создайте новый дроплет с самого начала, по уму, как в этом руководстве. Пример поиска.
7. Как добавить доменное имя к уже существующему дроплету
Это делается совсем не трудно, всего в несколько шагов. В настройках DNS вашего доменного имени указать настройки:
apps.mydomain.com. IN A [Droplet IP address]
*.apps.mydomain.com. IN A [Droplet IP address]
В дроплете зайти в папку dokku и открыть для редактирования HOSTNAME:
$ cd /home/dokku/
$ vim HOSTNAME
Нажать клавишу "i" и записать в файле "HOSTNAME" доменное имя вместо IP адреса; затем нажать Esc, кнопки :wq и Enter. Ура! Мы только что успешно использовали легендарный Vim!
Чтобы проекты запускались на поддоменах, нужно создать файл VHOST:
$ touch VHOST
И записать в файле доменное имя таким же способом, как это было в предыдущем пункте. В противном случае проекты будут доступны через порт. Теперь надо перезалить проект, а перед этим удалить его из dokku:
$ dokku delete app_name
Удалить в репозитории предыдущий remote с IP-адресом в названии:
Привет! Мы запилили поддержку Node.js на всех тарифных планах виртуального хостинга (не на VDS/VPS и не на облаке, а на shared!) и сейчас очень нуждаемся в обратной связи, а для этого нужно больше живых проектов на Node.js.
Что нужно знать:
В каталоге с приложением ( ~/domains/example.org/public_html ) создаем файл app.js со следующим содержимым:
require(‘/home/login/domains/example.org/public_html/index.js’);
process.chdir(‘/home/login/domains/example.org/public_html’);
Создаем файл .htaccess в этом же каталоге и добавляем в него правило:
PassengerStartupFile app.js
PassengerResolveSymlinksInDocumentRoot on
Require all granted
PassengerAppType node
PassengerAppRoot /home/login/domains/example.org/public_html
Options -MultiViews
Привет! Мы запилили поддержку Node.js на всех тарифных планах виртуального хостинга (не на VDS/VPS и не на облаке, а на shared!) и сейчас очень нуждаемся в обратной связи, а для этого нужно больше живых проектов на Node.js.
У всех тарифов есть бесплатный тестовый период: https://sprinthost.ru. Регистрируйтесь, создавайте приложение, присылайте замечания, пожелания и вопросы на support@sprinthost.ru или в группу https://vk.com/sprinthost, мы будем бесконечно благодарны.
Что нужно знать:
В каталоге с приложением ( ~/domains/example.org/public_html ) создаем файл app.js со следующим содержимым:
require(‘/home/login/domains/example.org/public_html/index.js’);
process.chdir(‘/home/login/domains/example.org/public_html’);
Создаем файл .htaccess в этом же каталоге и добавляем в него правило:
PassengerStartupFile app.js
PassengerResolveSymlinksInDocumentRoot on
Require all granted
PassengerAppType node
PassengerAppRoot /home/login/domains/example.org/public_html
Options -MultiViews
Для работы приложений у нас используется Phusion Passenger https://www.phusionpassenger.com/#about