Виртуальный хост для отдельного пользователя с PHP-FPM и nginx
Недавно, нужно было настроить виртуальный хост для отдельного пользователя с PHP-FPM и nginx и я немного погуглил, нашел решение. Выложу в качестве заметки «Виртуальный хост для отдельного пользователя с PHP-FPM и nginx».
В php-fpm можно создавать и управлять пулами (pool) процессов, которые имеют название”воркеры” (workers), они получают и обрабатывают PHP файлы которые находятся в домашней директории вашего сайта.
И так, у меня имеется уже настроенный (установленный) NGINX с PHP-FPM со следующим сайтом:
# vim /etc/nginx/conf.d/linux-notes.org.conf
У меня данный конфиг выглядит так:
server { listen 80; server_name linux-notes.org www.linux-notes.org; access_log /var/log/nginx/access-linux-notes.org.log main; error_log /var/log/nginx/error-linux-notes.org.log; include conf.d/gzip.conf; root /home/www/linux-notes/public_html; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$args; } # PHP-FPM # PHP scripts -> PHP-FPM server listening on 127.0.0.1:9000 location ~ \.php$ { # The following line prevents malicious php code to be executed through some uploaded file (without php extension, like image) # This fix shoudn't work though, if nginx and php are not on the same server, other options exist (like unauthorizing php execution within upload folder) # More on this serious security concern in the "Pass Non-PHP Requests to PHP" section, there http://wiki.nginx.org/Pitfalls try_files $uri =404; # PHP # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_intercept_errors on; fastcgi_ignore_client_abort off; fastcgi_connect_timeout 60; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffers 4 256k; fastcgi_buffer_size 128k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; } #---------------------------------------------------------- # Define default caching of 24h expires 86400s; add_header Pragma public; add_header Cache-Control "max-age=86400, public, must-revalidate, proxy-revalidate"; # Rewrite for versioned CSS+JS via filemtime location ~* ^.+\.(css|js)$ { rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last; expires 31536000s; access_log off; log_not_found off; add_header Pragma public; add_header Cache-Control "max-age=31536000, public"; } # Aggressive caching for static files location ~* \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|otf|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|t?gz|tif|tiff|ttf|wav|webm|wma|woff|wri|xla|xls|xlsx|xlt|xlw|zip)$ { expires 31536000s; access_log off; log_not_found off; add_header Pragma public; add_header Cache-Control "max-age=31536000, public"; } #---------------------------------------------------------- gzip on; gzip_types text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon; location ~ \.(css|js)$ { expires max; break; } location ~ \.(rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ { expires 3600; break; } location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ { expires max; break; } add_header "X-UA-Compatible" "IE=Edge,chrome=1"; #---------------------------------------------------------- location ~ /(\.|wp-config.php|readme.html|license.txt) { return 404; } if ($request_method !~ ^(GET|POST|HEAD)$ ) { return 444; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) location ~ /\.ht { deny all; access_log off; log_not_found off; } # Deny access to any files with a .php extension in the uploads directory # Works in sub-directory installs and also in multisite network # Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) location ~* /(?:uploads|files)/.*\.php$ { deny all; #access_log off; #log_not_found off; } # deny access to WP config file and license.txt and readme.html files location ~ /(\.|wp-config.php|readme.html|license.txt) { deny all; } # deny access to .conf files location ~* \.(conf)$ { deny all; } # Add trailing slash to */wp-admin requests. rewrite /wp-admin$ $scheme://$host$uri/ permanent; # Uncomment one of the lines below for the appropriate caching plugin (if used). include global/w3-total-cache.conf; }
Это готовый конфиг для вордпреса с кэшем и его можно юзать.
Создам php_info.php с кодом:
# echo "<?php echo phpinfo(); ?>" > /home/www/linux-notes/public_html/php_info.php
Можно посмотреть информацию о установленных модулях и не только.
Сейчас, я создам и настрою новый пул для моего сайта с PHP-FPM. Все настройки для пулов в CentOS сохраняется в папке /etc/php-fpm.d/, если используете Debian/Ubuntu/Mint, то они сохраняются в /etc/php5/fpm/pool.d/, есть и файл ссо стандартными настройками для пула всех сайтов с названием www.conf. Все настройки php-fpm хранятся в конфигурационном файле /etc/php-fpm.conf.
Скопирую уже готовый ( стандартный) конфиг для одного из моих сайтов (луче называть их по имени сайта):
# cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/linux-notes.org.conf
Открываем и находим:
; Start a new pool named 'www'. [linux-notes.org] имя пула (для каждого должно быть уникальным); ; Note: This value is mandatory. listen = 127.0.0.1:9000
Пока ничего не выполняем в данном файле, я потом вернусь к нему.
[...] user = apache group = apache [...]
Это пользователь и его группа, от имени которого будут выполняться файлы;
listen – тут стоит юзать либо порт (для каждого пула, но кроме 9000 порта, т.к он занят пулом www), так же, можно использовать unix-сокет. Я, для своих целей, использую порт.
Опции user и group – это задаем владельца на обработку файлов php;
Получаем такой конфиг:
[linux-notes.org] listen = 127.0.0.1:9001 user = captain group = captain
Сохраните все, а так же перезапустите PHP-FPM:
# service php-fpm restart
Для уверенности, можно проверить данный порт — 9001:
# netstat -anpt | grep 9001
Теперь, снова открываем конфиг NGINX с сайтом – у меня это файл/etc/nginx/conf.d/linux-notes.org.conf ищем строку, а так же меняем:
[...] fastcgi_pass 127.0.0.1:9000; [...]
на:
[...] fastcgi_pass 127.0.0.1:9001; [...]
Порт 9001 -порт пула PHP-FPM.
После всех изменений, стоит проверить конфигурацию конфига nginx:
# nginx -t
Далее, выполняем рестарт сервера nginx:
# service nginx restart
Убедимся, что пользователь запущен от которого запущен пул моего сайта:
# ps aux | grep -E 'php-fpm.*captain' [...] captain 6036 0.4 1.2 897904 79968 ? S May04 6:15 php-fpm: pool captain captain 6037 0.4 1.0 887920 67100 ? S May04 6:27 php-fpm: pool captain captain 6039 0.4 1.2 899324 78504 ? S May04 6:33 php-fpm: pool captain captain 6040 0.4 1.1 963748 75332 ? S May04 6:29 php-fpm: pool captain [...]
И проверяем работу сайта.
Статья «Виртуальный хост для отдельного пользователя с PHP-FPM и nginx» завершена.
Hey, thanks for the blog article. Really looking forward to read more. Much obliged.