Nginx + PHP-FPM


Optimized for Wordpress on 1CPU + 1GB Mem

/etc/php-fpm.d/www.conf
[www]
user = nobody
group = mobody
listen = 127.0.0.1:9000
listen.owner = nobody
listen.group = nobody
listen.mode = 0664
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 20
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 5
pm.process_idle_timeout = 3s;
pm.max_requests = 500

pm.status_path=/fpm-status
ping.path=/fpm-ping

;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
slowlog = /var/log/php-fpm/www-slow.log
;request_slowlog_timeout = 0
request_terminate_timeout = 0
;rlimit_files = 1024
;rlimit_core = 0

php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M

php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache
;php_value[opcache.file_cache]  = /var/lib/php/opcache
/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
worker_rlimit_nofile 1048576;
events {
    use                 epoll;
    worker_connections  4096;
    multi_accept        on;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  cloudflare  '$HTTP_CF_CONNECTING_IP - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for"';
    log_format  extended '$remote_addr $request_time $remote_user [$time_local] "$request" '
                         '$status $body_bytes_sent "$request_body" $msec $upstream_addr';
    access_log                  off;
    error_log                   off;
#   access_log          syslog:server=10.10.0.55,tag=nginx_access extended;
#   error_log           syslog:server=10.10.0.55,tag=nginx_error;
    sendfile                    on;
    sendfile_max_chunk          128k;
    send_timeout                3;
    tcp_nopush                  on;
    tcp_nodelay                 on;
    reset_timedout_connection   on;
    client_header_timeout       3;
    client_body_timeout         5;
    client_header_buffer_size   2k;
    client_body_buffer_size     256k;
    client_max_body_size        100m;
    keepalive_timeout           65;
    gzip                        on;
    gzip_disable		"msie6";
    gzip_types			text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
}
/etc/nginx/conf.d/default.conf
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_req_status 444;

server {
    listen 80;
    server_name 127.0.0.1;
    keepalive_timeout 0;
    allow 127.0.0.1;
    deny all;
    location = /status {
        stub_status on;
    }
    location ~ ^/(fpm-status|fpm-ping)$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
        include fastcgi_params;
    }
    access_log off;
    error_log off;
}

server {
    listen 80;
    listen 443 ssl http2;
    server_name domain.ru www.domain.ru;
    ssl_certificate         /etc/letsencrypt/live/domain.ru/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/domain.ru/privkey.pem;
    access_log          /var/log/nginx/domain.ru-access.log main;
    error_log           /var/log/nginx/domain.ru-error.log;
    set $basedir "/data/www/domain.ru";
    root $basedir/htdocs;
    index index.php index.html index.htm;
    client_max_body_size 0;
    location /.well-known/ {
        alias /data/.well-known/;
    }
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;
    location = /wp-login.php {
        limit_req       zone=one  burst=1 nodelay;
        include fastcgi_params;
        fastcgi_pass    127.0.0.1:9000;
    }
    location ~ \.php$ {
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PHP_VALUE       "open_basedir=$basedir;";
        include /etc/nginx/fastcgi_params;
    }
    location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        expires max;
    }
    location = /robots.txt {
        access_log off;
        log_not_found off;
    }
    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }
    error_page 404 /index.php;
}

/etc/my.cnf
[mysqld]
port            = 3306
socket          = /var/lib/mysql/mysql.sock
skip_name_resolve
skip-external-locking
open_files_limit       = 65535
lower_case_table_names = 1
symbolic-links=0

server-id       = 1
default_storage_engine=InnoDB

max_connections         = 10000
connect_timeout         = 5
wait_timeout            = 600
max_allowed_packet      = 16M
thread_cache_size       = 128
sort_buffer_size        = 4M
bulk_insert_buffer_size = 16M
tmp_table_size          = 32M
max_heap_table_size     = 32M

innodb_buffer_pool_size = 128M
innodb_log_buffer_size  = 4M
innodb_file_per_table   = 1
innodb_open_files       = 4000
innodb_io_capacity      = 4000
innodb_flush_method     = O_DIRECT

Zabbix monitoring

- template.nginx.xml
- template.php-fpm.xml

vi /etc/zabbix/zabbix_agentd.d/nginx-php-fpm.conf
# nginx
UserParameter=nginx.status.active,  /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| grep Active | awk '{print $3}'
UserParameter=nginx.status.accepts, /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| awk NR==3 | awk '{print $1}'
UserParameter=nginx.status.handled, /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| awk NR==3 | awk '{print $2}'
UserParameter=nginx.status.requests,/usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| awk NR==3 | awk '{print $3}'
UserParameter=nginx.status.reading, /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| grep 'Reading' | awk '{print $2}'
UserParameter=nginx.status.writing, /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| grep 'Writing' | awk '{print $4}'
UserParameter=nginx.status.waiting, /usr/bin/curl -s "http://localhost:80/status" 2>/dev/null| grep 'Waiting' | awk '{print $6}'

# php-fpm
UserParameter=php-fpm.status[*],/usr/bin/curl -s http://localhost:80/fpm-status | grep "$(echo '$1' | sed 's/-/ /g')" | cut -d : -f 2 | awk '{print $$1}'