Linux, программирование, Я!

Nginx + PHP-fcgi на Ubuntu

Если быть точным, опишу переход с режима работы Nginx <-> Apache backend на Nginx <-> php-fcgi backend.

Т.е. об отказе от промежуточного, в общем-то бесполезного слоя в виде апача между Nginx (http сервер) и PHP (application сервер)

Отдельно хочу заметить, что в этом руководстве мы обойдемся без компиляции чего-бы то ни было

Что имеем на данный момент:

Имеется домен с поддоменами, сервер на Ubuntu 9.10 с веб-сервером Nginx, который слушает 80 порт, и Апач с mod-php, висящий на localhost:8080 (в качестве прокси-бэкенда нгинкса). Для коннекта к апачу в /etc/nginx/sites-enabled лежит симлинк на файлик 100apache_proxy следующего содержания:

server {
listen       80;
server_name  seriyps.ru *.seriyps.ru localhost;
access_log  /var/log/nginx/apache_proxy.access.log;
location / {
	proxy_pass      http://localhost:8080;#проксируем данные на апач
	proxy_connect_timeout 15;#время ожидания ответа от апача - 15 секунд, можно больше
	proxy_redirect  off;
	proxy_set_header	Host    $host;#Ставим HTTP заголовок Host
	proxy_set_header	X-Real-IP $remote_addr;#Заголовок X_Real-Ip т.к. внешние запросы принимает NGINX а апачу достаются в качестве IP только 172.0.0.1
	proxy_set_header	X-Forwarded-For $proxy_add_x_forwarded_for;#то-же самое
}

В итоге хотим:

ПЛАВНО перейти с использования apache прослойки на полное использование nginx<->php-fcgi с минимальными простоями сервера.

Приступим!

Настройка PHP для работы в режиме fast-CGI

Для начала поставим пакет php5-cgi (он нужен для использования PHP отдельно от apache)

bash
  1. sudo apt-get install php5-cgi

Затем ставим пакетик spawn-fcgi Эта утилитка нужна для удобного управления fast-cgi процессами независимо от веб-сервера.

bash
  1. sudo apt-get install spawn-fcgi

После чего создаем скрипт для запуска php5-fcgi процесса через spawn-fcgi

bash
  1.  
  2. #!/bin/sh
  3. ### BEGIN INIT INFO
  4. # Provides: php5-fcgi
  5. # Required-Start: $all
  6. # Required-Stop: $all
  7. # Default-Start: 2 3 4 5
  8. # Default-Stop: 0 1 6
  9. # Short-Description: starts the php5-cgi in fast-cgi mode
  10. # Description: configure and starts php5-cgi processes in fast-cgi mode using spawn-fcgi
  11. ### END INIT INFO
  12.  
  13. PATH=/sbin:/bin:/usr/sbin:/usr/bin
  14. SCRIPTNAME="/etc/init.d/php5-fcgi"
  15.  
  16. FCGI_PIDFILE="/var/run/spawn-php5-fcgi.pid"
  17. ## Абсолютный путь до spawn-fcgi
  18. FCGI_DAEMON="/usr/bin/spawn-fcgi"
  19.  
  20. ## php переключится на этого юзера и группу (делать такими-же, как у апача)
  21. USER=www-data
  22. GROUP=www-data
  23. ## Абсолютный путь до php
  24. FCGI_PROGRAM="/usr/bin/php5-cgi"
  25. ## Количество запущенных процессов PHP-fcgi, см http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:PerformanceFastCGI#How-many-PHP-processes-do-I-need
  26. PHP_FCGI_CHILDREN=10
  27. ## максимальное количество запросов, которое обработает отдельный PHP - fcgi процесс до своего перезапуска
  28. PHP_FCGI_MAX_REQUESTS=1000
  29. ## TCP порт, который будет слушать php-fcgi
  30. FCGI_PORT="9000"
  31. ## IP адреса, по которым будет доступен PHP-fcgi (через запятую)
  32. FCGI_IP="127.0.0.1"
  33.  
  34. test -x $FCGI_PROGRAM || exit 0
  35. test -x $FCGI_DAEMON || exit 0
  36.  
  37. set -e
  38.  
  39. export PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS
  40.  
  41. . /lib/lsb/init-functions
  42.  
  43. case "$1" in
  44. start)
  45. log_daemon_msg "Starting spawn-fcgi"
  46. if ! $FCGI_DAEMON -a $FCGI_IP -p $FCGI_PORT -f $FCGI_PROGRAM -u $USER -g $GROUP -C $PHP_FCGI_CHILDREN -P $FCGI_PIDFILE; then
  47. log_end_msg 1
  48. else
  49. log_end_msg 0
  50. fi
  51. RETVAL=$?
  52. ;;
  53. stop)
  54. log_daemon_msg "Killing all spawn-fcgi processes"
  55. start-stop-daemon --stop --pidfile $FCGI_PIDFILE --signal 2 && log_end_msg 0 || log_end_msg 1
  56. #if killall --signal 2 php5-cgi > /dev/null 2> /dev/null; then
  57. # log_end_msg 0
  58. #else
  59. # log_end_msg 1
  60. #fi
  61. RETVAL=$?
  62. ;;
  63. restart|force-reload)
  64. $0 stop
  65. #sleep 1
  66. $0 start
  67. ;;
  68. *)
  69. echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
  70. exit 1
  71. ;;
  72. esac
  73.  
  74. exit $RETVAL
  75.  

Этот скрипт – несколько адаптированная версия скрипта из примера в документации сервера lighttpd http://redmine.lighttpd.net/projects/lighttpd/wiki/ScriptsUbuntu приспособленная для работы с rc.d правилами Ubuntu/Debian. Можно сделать попроще – см http://redmine.lighttpd.net/projects/spawn-fcgi/wiki/Basic_Ideas но в таком случае за перезапуском PHP при загрузке придется следить самостоятельно

Сохраняем этот скрипт как /etc/init.d/php5-fcgi и даем права на исполнение:

bash
  1. sudo chmod +x /etc/init.d/php5-fcgi

Обновляем правила rc.d для автоматического запуска php5-fcgi при старте системы:

bash
  1. sudo update-rc.d php5-fcgi defaults

Запускаем:

bash
  1. sudo service php5-fcgi start

spawn-fcgi: child spawned successfully: PID: 23620

Проверяем:

bash
  1. ps xa | grep php5-cgi

Должен выдать что-то вроде

23620 ?        Ss     0:00 /usr/bin/php5-cgi
23622 ?        S      0:00 /usr/bin/php5-cgi
23623 ?        S      0:00 /usr/bin/php5-cgi
23624 ?        S      0:00 /usr/bin/php5-cgi
23625 ?        S      0:00 /usr/bin/php5-cgi
23626 ?        S      0:00 /usr/bin/php5-cgi
23627 ?        S      0:00 /usr/bin/php5-cgi
23628 ?        S      0:00 /usr/bin/php5-cgi
23629 ?        S      0:00 /usr/bin/php5-cgi
23630 ?        S      0:00 /usr/bin/php5-cgi
23631 ?        S      0:00 /usr/bin/php5-cgi

Если вы видите то-же самое, значит, скорее всего, все сделано правильно! Обратите внимание на процесс 23620 ? Ss 0:00 /usr/bin/php5-cgi – это что-то наподобие мастер-процесса, он является родителем для остальных процессов php5-cgi. Убиваем его – убиваем все процессы php5-cgi.
Первая часть настройки закончена!

Настройка Nginx для работы с php-fcgi

Тут все просто (если не нужно настраивать url-rewrite правила).
В папочке /etc/nginx/sites-available создаем файлик, например 20yourdomain.com примерно следующего содержания:

#/etc/nginx/sites-available/20yourdomain.com
server {
	listen   80;
	server_name  yourdomain.com;

	access_log  /var/log/nginx/yourdomain_com.log;
	root   /var/www/yourdomain.com;
	index  index.php index.html index.htm;

	# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9090
	#
	location ~ \.php$ {
		fastcgi_pass   127.0.0.1:9000;
		fastcgi_index  index.php;
		fastcgi_param  SCRIPT_FILENAME  /var/www/yourdomain.com$fastcgi_script_name;
		include fastcgi_params;
	}
	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	location ~ /\.ht {
		deny  all;
	}

}

(места, выделенные жирным шрифтом замените на ваши данные)

Создаем на него символическую ссылку в /etc/nginx/sites-enabled

bash
  1. sudo ln -s /etc/nginx/sites-available/20yourdomain.com /etc/nginx/sites-enabled/20yourdomain.com

Проверяем правильность конфига

bash
  1. sudo service nginx configtest

Testing nginx configuration: the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful
nginx.

Готово! перезапускаем Nginx

bash
  1. sudo service nginx restart

и наслаждаемся! При необходимости проделываем эту процедуру для каждого поддомена, добавляем правила URL-rewrite и наслаждаемся еще больше.

4 комментариев to Nginx + PHP-fcgi на Ubuntu

  1. enottrue's Gravatar enottrue
    13.11.2009 at 16:39 | #

    прям в начале статьи sudo apt-get install spawn-fcgi 2 раза. install php5-cgi нет.
    а в остальном спасибо за труд)

  2. 30.11.2009 at 17:41 | #

    Первое (и последнее) на чем запоролся в этой статье это:
    FCGI_PORT=\9090\
    в нгинксе дефолтом 9000 порт стоит, может в статейке стоило б сменить в скрипте запуска порт?
    В чем магическая разница запуска php-cgi на 9000 и на 9090 порте?
    А за статью огромное спасибо, особенно скрипт запуска очень выличил!

Оставить комментарий

Вы можете использовать следующие HTML теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>