Как известно, в комплекте с Mac OS X идет веб-сервер apache и php. Но как быть, если мы хотим использовать node.js, да не просто как отдельный сервер, висящий на отдельном порту, а иметь возможность проксировать http-запросы как к нему, так и к php. Небольшая инструкция по замене штатного httpd/php-module на связку nginx+php-fpm+node.js ниже.
Начнем по порядку.
1. Отключение загрузки httpd при старте системы.
В Mac OS httpd, как впрочем и многие другие демоны и сервисы, грузится как LaunchDaemon. Все управление осуществляется через launchctl.
# Так можно загрузить httpd. Ключик -w делает эту загрузку перманентной, то есть после презагрузки компа сервис загрузится автоматически. kostik@KOsTIK: ~> sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist # Ну а так соответственно можно остановить http, а благодаря ключу -w он не будет больше загружаться автоматически при старте системы. kostik@KOsTIK: ~> sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
2. Установка Nginx.
Есть несколько способов установить Nginx:
- Установка из исходников
- Установка через macports
- Установка через homebrew
Лично я как-то перешел с macports на homebrew, поэтому выбрал третий вариант. Тем более, что в brew доступна версия 1.4.1 и даже 1.5.0, а в macports только 1.4.1. Но, правда для меня это не принципиально, главное что там уже есть поддержка проксирования веб-сокетов.
Установка из homebrew крайне проста.
kostik@KOsTIK: ~> brew search nginx nginx kostik@KOsTIK: ~> brew info nginx nginx: stable 1.4.1, devel 1.5.0, HEAD http://nginx.org/ https://github.com/mxcl/homebrew/commits/master/Library/Formula/nginx.rb ==> Dependencies Required: pcre ==> Options --with-debug Compile with support for debug log --with-gunzip Compile with support for gunzip module --with-passenger Compile with support for Phusion Passenger module --with-spdy Compile with support for SPDY module --with-webdav Compile with support for WebDAV module ==> Caveats Docroot is: /usr/local/var/www The default port has been set to 8080 so that nginx can run without sudo. If you want to host pages on your local machine to the wider network you can change the port to 80 in: /usr/local/etc/nginx/nginx.conf You will then need to run nginx as root: `sudo nginx`. You should reload nginx: launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist kostik@KOsTIK: ~> brew install nginx --with-spdy ==> Downloading http://nginx.org/download/nginx-1.4.1.tar.gz Already downloaded: /Library/Caches/Homebrew/nginx-1.4.1.tar.gz ==> Patching patching file conf/nginx.conf ==> ./configure --prefix=/usr/local/Cellar/nginx/1.4.1 --with-http_ssl_module --with-pcre --with-ipv6 --sbin-path=/usr/local/Cellar/nginx/1.4.1/bin/nginx --with-cc-opt=-I/usr/local/include --with-ld-opt=-L/usr/local/lib --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-bo ==> make ==> make install ==> Caveats Docroot is: /usr/local/var/www The default port has been set to 8080 so that nginx can run without sudo. If you want to host pages on your local machine to the wider network you can change the port to 80 in: /usr/local/etc/nginx/nginx.conf You will then need to run nginx as root: `sudo nginx`. To have launchd start nginx at login: ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents Then to load nginx now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist ==> Summary /usr/local/Cellar/nginx/1.4.1: 7 files, 948K, built in 16 seconds
Не знаю, как в macports, а в homebrew что прекрасно, это то, что в комплекте с самим nginx’ом идет уже готовый plist для launchd, поэтому можно сразу прописать автостарт демона при загрузке ОС. Сделать это можно командами, указанными brew:
kostik@KOsTIK: ~> ln -sfv /usr/local/opt/nginx/*.plist ~/Library/LaunchAgents kostik@KOsTIK: ~> launchctl load ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
Однако, если вы хотите повесить nginx на 80 порт, это потребует запуска демона из-под рута. Для этого необходимо немного подправить этот plist и положить его в папку системных LaunchDaemons. Поскольку мы будем запускать его как демона, а поставляемый plist предназначен для запуска nginx из-под пользователя и под управлением launchd, надо удалить в plist строчки про отключение демонизации. Вот подправленный файлик и команды для запуска как LaunchDaemon:
Label ksdaemon.ru.nginx RunAtLoad KeepAlive ProgramArguments /usr/local/opt/nginx/bin/nginx WorkingDirectory /usr/local
kostik@KOsTIK: ~> sudo cp ksdaemon.ru.nginx.plist /System/Library/LaunchDaemons kostik@KOsTIK: ~> sudo chown root:wheel /System/Library/LaunchDaemons/ksdaemon.ru.nginx.plist kostik@KOsTIK: ~> sudo launchctl load /System/Library/LaunchDaemons/ksdaemon.ru.nginx.plist
Если использовать macports, nginx ставится так же одной командой: sudo port install nginx.
Опустим процесс настройки nginx. Он такой же как везде. Тонкости настройки проксирования будут показаны позже.
3. Установка node.js
Это, пожалуй, самый простой пункт, потому что готовый установочный пакет можно скачать прямо на сайте ноды: nodejs.org/download. Качаем, ставим.
4. Php-fpm у нас уже есть, так что ничего ставить дополнительно не надо.
5. Проксирование запросов к php-fpm в nginx.
Здесь все как всегда: в настройках виртуального хоста прописываем обращение к fastcgi.
kostik@KOsTIK: ~> vim /etc/nginx/vhost.d/project-host.conf location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
Можно, кстати, сразу повесить nginx на стандартный, 80 порт, потому как апачи уже остановлен.
6. Теперь сделаем, чтобы php-fpm запускался при старте системы.
Для этого надо написать plist-файлик для launchd. А так как запускать php-fpm нужно от рута (это если оставить в конфиге переключение на nobody или же на www), то этот plist нужно так же положить в папку системных демонов.
Вот мой вариант plist для запуска php-fpm
Label ksdaemon.ru.php-fpm RunAtLoad KeepAlive ProgramArguments /usr/sbin/php-fpm -c /private/etc/php.ini -y /private/etc/php-fpm.conf WorkingDirectory /usr
Ну и положим этот файлик куда надо и загрузим.
kostik@KOsTIK: ~> sudo cp ksdaemon.ru.php-fpm.plist /System/Library/LaunchDaemons/ kostik@KOsTIK: ~> sudo chown root:wheel /System/Library/LaunchDaemons/ksdaemon.ru.php-fpm.plist kostik@KOsTIK: ~> sudo launchctl load /System/Library/LaunchDaemons/ksdaemon.ru.php-fpm.plist
Теперь у нас при загрузке Mac OS автоматом стартуют nginx и php-fpm.
7. Проксирование веб-сокет запросов.
Осталось настроить проксирование веб-сокет запросов к node.js (для тех, кому это нужно) и настроить автостарт node.js, опять же, если это необходимо.
Для проксирования веб-сокетов надо прописать в конфиге виртуального хоста, ну или же всего веб-сервера, если он у вас один, следующее:
kostik@KOsTIK: ~> vim /etc/nginx/vhost.d/project-host.conf # websockets location /socket/ { proxy_pass http://127.0.0.1:5000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; }
Теперь все запросы по адресу http://your-server/socket/* будут проксироваться на адрес http://127.0.0.1:5000/, на котором мы запустим ноду.
8. Для автостарта ноды надо так же написать plist и положить его в LaunchAgents.
Вот мой вариант plist для автозапуска node.js
Label ksdaemon.ru.node-js RunAtLoad KeepAlive ProgramArguments /usr/local/bin/node /Users/kostik/Projects/my-project/index.js WorkingDirectory /usr
Ну и положим этот файлик куда надо и загрузим. Поскольку ноду нет необходимости запускать от рута, то положим ее в пользовательские LaunchAgents
kostik@KOsTIK: ~> cp ksdaemon.ru.node-js.plist ~/Library/LaunchAgents/ kostik@KOsTIK: ~> launchctl load ~/Library/LaunchAgents/ksdaemon.ru.node-js.plist
Если кому надо, можно скачать мои готовые plist’ы:
ksdaemon.ru.nginx.plist
ksdaemon.ru.php-fpm.plist
ksdaemon.ru.node-js.plist
Ну вот собственно и все. Теперь сам не забуду, а может и еще кому-то пригодится 🙂