Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Сервер в связке Nginx + NodeJs

Сервер в связке Nginx + NodeJs

Данная пошаговая инструкция поможет освоить основы на простом примере

Для справки

Сервер поднимался на Debian 8 c характеристиками:

CPU - 1 ядро x 500 МГц

RAM - 512 МБ

Диск - 5 ГБ SSD+HDD

Принцип работы на пальцах

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

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

Представим что у вас чистый сервер и ничего не установлено. Идем в папку /root и становим Nginx:

$ apt-get install -y nginx

После установки Nginx, в папке /var появилась папка /www, а в ней папка /html, а в ней файл index.html. Идем в папку /var и переименуем папку /html в папку /nginx:

$ mv /var/www/html /var/www/nginx

Создаем доп.файл style.css (для теста):

$ touch /var/www/nginx/style.css

В файле index.html пишем код, этот файл будет заглушкой:

<h1>Заглушка</h1>

В файле style.css пишем код:

* {background: #000;}

Еще нам нуно создать папку для NodeJS:

$ mkdir /var/www/nodejs

Далее прописывем на всякий случай права для папок:

$ chown www-data /var/www && chown www-data /var/www/nginx && chown www-data /var/www/nodejs

Теперь самое интересное, настраиваем файл конфига Nginx, редактируем файл default:

$ mcedit /etc/nginx/sites-available/default

Очищаем весь файл и пишем (комменты # ниже):

# Настройка сервера
server {
	# Nginx слушает порт 80
	# default_server - указан в /etc/nginx/nginx.conf
	listen 80 default_server;
	# Указываем "динамическую" папку NodeJS
	root /var/www/nodejs;
	# Указываем основной файл заглушки
	index index.html;
	# Устанавливаем страницы ошибок
	# В папке /var/www/errors должны быть файлы 
	# 50x.html и 40x.html соответственно
	error_page 500 502 503 504 /50x.html;
	error_page 400 401 402 403 404 /40x.html;
	location = /50x.html { 
		root /var/www/errors;
	}
	location = /40x.html { 
		root /var/www/errors;
	}
	# Указываем IP адрес сервера
	server_name IP_адрес_сервера;
	# Если мы обращаемся по любому УРЛ начиная с /
	# то сервер будет обрабатывать NodeJS
	location / {
		# Тут указываем IP|Url и порт (8000) для NodeJS
		# поскольку Nginx будет висеть на 80 порту
		proxy_pass http://IPorURL_адрес_сервера:8000;
		proxy_set_header Host $host;
	}
	# Если мы обращемся по УРЛ начинающийся с /nginx/
	# то мы будем подгружать "статичные" файлы хранящиеся в нем
	# в соответствии с наличием этих файлов в этой папке
	location /nginx/ {
		# Указываем корень
		root /var/www/;
		autoindex off;
		# Итого путь для Nginx будет
		# /var/www/static/
	}
}	 

Добавляем Nginx в автозагрузку и запускаем, что бы изменения применились, после проверяем статус:

$ systemctl enable nginx && systemctl start nginx && systemctl status nginx

Установка и настройка NodeJS

Идем в папку /root и под пользователем root устанавливаем cURL

$ apt-get install -y curl

С помощью cURL скачиваем NodeJS, в моем случае верся 6:

$ curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh

Запускаем скаченный файл:

$ bash nodesource_setup.sh

Устанавливаем NodeJS

$ apt-get install -y nodejs build-essential

Готово! Можно протестировать:

$ node
> console.log ('hello world')

Вместе с NodeJS установился и NPM (Node Package Manager), с помощью которого мы установим express и pm2:

С помощью демона pm2 можно позабыть о проблемах с падением NodeJS (устанавливаем глобально):

$ npm install pm2 -g

Инициализируем проект, создаем package.json в который будем фиксировать нужные пакеты (спасибо @niiu за подсказку)

$ npm init

С помощью библиотеки express код будет писаться намного проще и быстрее (устанавлиаем локально):

$ cd /var/www/nodejs/
$ npm install express --save

Создаем файл server.js для NodeJS, который будет основным (входным) файлом:

$ touch /var/www/nodejs/server.js

Код файла server.js описан ниже:

  // Настройки
  const setup = {port:8000}
  // Подключаем express
  const express = require ('express'); 
  // создаем приложение
  const app = express ();
  // Маршрутизируем GET-запрос http://ваш_сайт/test
  app.get('/test', (req, res) => {    
    res.send('Тест'); 
  });
  // Слушаем порт и при запуске сервера сообщаем
  app.listen(setup.port, () => {
    console.log('Сервер: порт %s - старт!', setup.port);
  });

Теперь можно добавить демону 1 процесс и запустить наш NodeJS сервер:

$ pm2 start /var/www/nodejs/server.js

При этом у нас запущен сервер Nginx

После перезагрузки ОС, pm2 сам себя не запустит и соответственно не запустит процессы. Выполняем команды:

  1. Сначала добавляем нужный процесс (в нашем случае скрипт NodeJS)
  2. Потом сохраняем конфигурацию
  3. После, добавляем PM2 в сервисы ОС
$ pm2 start server.js
$ pm2 save
$ pm2 startup

Готово

Если все запустилось, значит у вас ровные руки, а у меня талант писать пошаговые инструкции :)

Тестируем

Переходим на http://IP_адрес_сайта:80/ - дожны увидеть фразу "Тест"

Переходим на http://IP_адрес_сайта:80/nginx/style.css - дожны увидеть код стилей

Переходим на http://IP_адрес_сайта:80/nginx/ или http://IP_адрес_сайта:80/nginx/index.html - дожны увидеть заглушку

Итого

Nginx является прокси-сервером, NodeJS основным приложением. Первый висит на 80 порту, второй на 8000 и слушает первый. NodeJS отдает динамику, а Nginx отвечает за статику.

Если что-то не получилось или вы нашли ошибку, пишите в комментариях ниже!

Полезные материалы

Сайт GitHub
https://nginx.org/ https://github.com/nginx/nginx
https://nodejs.org/ https://github.com/nodejs/node
http://expressjs.com/ https://github.com/expressjs/express
https://www.npmjs.com/ https://github.com/npm
https://www.npmjs.com/package/pm2
https://packages.debian.org/ru/jessie/curl
@olytv

This comment has been minimized.

Copy link

@olytv olytv commented Jun 29, 2018

Спасибо за гайд!
У Вас опечатки:

Идем в папку /root и под пользователем root устанавлиме cURL
С помощью демона pm2 можно позабыть о проблемах с падением NodeJS (устанавлиаем глобально):
С помощью библиотеки express код будет писаться намного проще и быстрее (устанавлиаем локально):

@BarmaleyHD

This comment has been minimized.

Copy link

@BarmaleyHD BarmaleyHD commented Jul 17, 2018

Thank you for this post!
You have talent and I have straight hands :D

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Jul 30, 2018

@BarmaleyHD - yeap!
@eneym - спасибо, исправил!

@racshaser

This comment has been minimized.

Copy link

@racshaser racshaser commented Nov 14, 2018

Спасибо!

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Dec 1, 2018

Спасибо!

@racshaser - всегда пожалуйста!

@IsaUgurchiev

This comment has been minimized.

Copy link

@IsaUgurchiev IsaUgurchiev commented Dec 3, 2018

Итого путь для Nginx будет
/var/www/static/

Почему static? Разве не /var/www/nginx/ ?

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Dec 22, 2018

@IsaUgurchiev,

Почему static? Разве не /var/www/nginx/ ?

При переходе в https://www.site.com/nginx/favicon.ico, Nginx будет сразу отдавать файл иконки, который находятся физически здесь /var/www/static/favicon.ico.

@niiu

This comment has been minimized.

Copy link

@niiu niiu commented Feb 25, 2019

Забыли команду npm init. Без неё express матерится на отсутствие package.json

@wrqqq

This comment has been minimized.

Copy link

@wrqqq wrqqq commented Feb 27, 2019

Спасибо.

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Apr 2, 2019

Спасибо.

@wrqqq, на здоровье!

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Apr 2, 2019

Забыли команду npm init. Без неё express матерится на отсутствие package.json

@niiu, внес правку в описание, спасибо за замечание!

@InitOzhogin

This comment has been minimized.

Copy link

@InitOzhogin InitOzhogin commented Jun 22, 2019

Спасибо!

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Jun 24, 2019

Спасибо!

@InitOzhogin, пожалуйста!

@newdecline

This comment has been minimized.

Copy link

@newdecline newdecline commented Aug 17, 2019

У меня после добавления в pm2 пишется в таблице status: errored

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Aug 26, 2019

status: errored

Как вариант: Unitech/pm2#2843 (comment)

@Bond1768

This comment has been minimized.

Copy link

@Bond1768 Bond1768 commented Jan 18, 2020

Чет не совсем понятно в начале файла конфигурации
Указываем "динамическую" папку NodeJS
root /var/www/nodejs;
а зачем указывать динамическую папку ноды что он там найдет? main.js? может это все таки папка где лежит html?

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Jan 19, 2020

Чет не совсем понятно в начале файла конфигурации
Указываем "динамическую" папку NodeJS
root /var/www/nodejs;
а зачем указывать динамическую папку ноды что он там найдет? main.js? может это все таки папка где лежит html?

@Bond1768, скорей я имел в виду динамику (то что генерит нода), а не статику

@Excelsiorer

This comment has been minimized.

Copy link

@Excelsiorer Excelsiorer commented Apr 20, 2020

Очень помогло, спасибо огромное! Пытаюсь поднять сервер для своего проекта, и только с вашим гайдом удалось это сделать!
Пока не могу понять почему при переходе по ссылке у меня отображается надпись "Cannot GET /", но с этим уже буду разбираться в следующий раз)

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Apr 21, 2020

Очень помогло, спасибо огромное! Пытаюсь поднять сервер для своего проекта, и только с вашим гайдом удалось это сделать!
Пока не могу понять почему при переходе по ссылке у меня отображается надпись "Cannot GET /", но с этим уже буду разбираться в следующий раз)

@Excelsiorer Это так отрабатывает expressjs (скорей всего на этом пути у вас нет маршрута или обработчика исклюяений)

@sergewhite

This comment has been minimized.

Copy link

@sergewhite sergewhite commented Apr 25, 2020

@tomasevich кажется логичней указывать в root папку со статикой и использовать try_files $uri /; В таком случае статика будет сразу отдаваться, остальное в ноду.

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Apr 27, 2020

@tomasevich кажется логичней указывать в root папку со статикой и использовать try_files $uri /; В таком случае статика будет сразу отдаваться, остальное в ноду.

@sergewhite, полностью согласен! На момент написания статьи, эти нюансы я не учитывал (возможно не осознавал)

@Demidov-Alex

This comment has been minimized.

Copy link

@Demidov-Alex Demidov-Alex commented May 29, 2020

@tomasevich Большое спасибо - очень помогло!

@dimbos

This comment has been minimized.

Copy link

@dimbos dimbos commented Aug 2, 2020

Добрый день. Подскажите, столкнулся с такой проблемой. Захожу в приложение по https и приложение не видит стили и скрипты.
В express указана папка со статическими файлами. Что с ними делать? Куда эту папку перенести? Ответа найти не могу. Какой путь указывать для стилей и скриптов.

@ratinart

This comment has been minimized.

Copy link

@ratinart ratinart commented Aug 13, 2020

Ты лучший, спасибо! Все заработало с пол оборота:)

@tomasevich

This comment has been minimized.

Copy link
Owner Author

@tomasevich tomasevich commented Oct 22, 2020

@Demidov-Alex, @ratinart - рад что статья оказалась полезна

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

Примеры

// если указать путь маршрута /static и название папки public
app.use('/static', express.static('public'));
// то при запросе к адресу http://site.com/static/style.css будет доступен файл
// расположенный по адресу /папка_проекта/public/style.css
// при чем как с http, так и с httpS будет работать одинаково

// еще пример
app.use('/aaa/555', express.static(__dirname + '/my_new_path''));
// то при запросе к адресу http://site.com/aaa/555/style.css будет доступен файл
// расположенный по адресу /папка_проекта/my_new_path/style.css
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment