Transcription
Optimizing NGINX & PHP-FPM— From Beginner to Expert to CrazyInternational PHP Conference Fall 2019 - Munich
Arne BlankertsCo-Founder, The PHP Consulting Company
Basics
location / {root/usr/share/nginx/html;index index.html index.htm;}location \.php {roothtml;fastcgi pass127.0.0.1:9000;fastcgi index index.php;includefastcgi params;fastcgi param SCRIPT FILENAME} document root fastcgi script name;
location / {root/usr/share/nginx/html;index index.html index.htm;}location \.php {roothtml;fastcgi pass127.0.0.1:9000;fastcgi index index.php;includefastcgi params;fastcgi param SCRIPT FILENAME}/var/www/php/ fastcgi script name;
location / {root/usr/share/nginx/html;index index.html index.htm;}location \.php {roothtml;fastcgi pass127.0.0.1:9000;fastcgi index index.php;includefastcgi params;fastcgi param SCRIPT FILENAME}/var/www/php/index.php;
location / {root/usr/share/nginx/html;index index.html index.htm;}location \.php {roothtml;fastcgi pass127.0.0.1:9000;fastcgi index index.php;includefastcgi params;fastcgi param SCRIPT FILENAME}/var/www/php/index.php;
location / {root/usr/share/nginx/html;index index.html index.htm;}location \.php {fastcgi pass127.0.0.1:9000;includefastcgi params;fastcgi param SCRIPT FILENAME}/var/www/php/index.php;
location / {root/usr/share/nginx/html;index index.html index.htm;try files uri uri/ @php;}location @php {fastcgi passincludefastcgi param}127.0.0.1:9000;fastcgi params;SCRIPT FILENAME/var/www/php/index.php;
root/usr/share/nginx/html;location / {try files uri uri/ @php;}location @php {fastcgi passincludefastcgi param}unix:/var/run/php-fpm.sock;fastcgi params;SCRIPT FILENAME /var/www/php/index.php;
Compress all the things!
root/usr/share/nginx/html;location / {gzip static on;try files uri uri/ @php;}location @php {gzip on;fastcgi passincludefastcgi param}unix:/var/run/php-fpm.sock;fastcgi params;SCRIPT FILENAME /var/www/php/index.php;
Content Security Policy
server {root/usr/share/nginx/html;add header Content-Security-Policy "default-src 'none'; img-src 'self'; \script-src 'self'; style-src 'self'; font-src 'self'; base-uri 'self'; \form-action 'self'; connect-src 'self'; frame-ancestors 'none'";}
server {root/usr/share/nginx/html;include content-security-policy;}
enerate
Additional Security Headers
server {root/usr/share/nginx/html;include content-security-policy;add header X-Frame-Options DENY;add header X-Content-Type-Options nosniff;add header X-Xss-Protection "1; mode block" always;}
Force Https
server {listen 80 default server;listen [::]:80 default server;return 301 https:// host request uri;}
Sane TLS
server {listen 443 ssl http2;listen [::]:443 ssl http2;ssl certificate /path/to/signed cert plus intermediates;ssl certificate key /path/to/private key;ssl session timeout 1d;ssl session cache shared:MozSSL:10m; # about 40000 sessionsssl session tickets off;ssl dhparam /path/to/dhparam.pem;ssl protocols TLSv1.2 TLSv1.3;ssl ciphers -SHA384;ssl prefer server ciphers off;add header Strict-Transport-Security "max-age 63072000" always;ssl stapling on;ssl stapling verify on;ssl trusted certificate /path/to/root CA cert plus intermediates;resolver 127.0.0.1;}
Paranoid TLS
server {listen 443 ssl http2;listen [::]:443 ssl http2;ssl certificate /path/to/signed cert plus intermediates;ssl certificate key /path/to/private key;ssl session timeout 1d;ssl session cache shared:MozSSL:10m; # about 40000 sessionsssl session tickets off;ssl protocols TLSv1.3;ssl prefer server ciphers off;add header Strict-Transport-Security "max-age 63072000" always;ssl stapling on;ssl stapling verify on;ssl trusted certificate /path/to/root CA cert plus intermediates;resolver 127.0.0.1;}
.mozilla.orghttps://securityheaders.com
More than one backend
location @php {fastcgi passincludefastcgi param}unix:/var/run/php-fpm.sock;fastcgi params;SCRIPT FILENAME /var/www/php/index.php;
upstream php-fpm {server unix:/var/run/php-fpm.sock;}location @php {fastcgi passincludefastcgi param}php-fpm;fastcgi params;SCRIPT FILENAME/var/www/php/index.php;
upstream php-fpm {server unix:/var/run/php-fpm.sock;server 192.168.1.1:9000 weigth 5;server 192.168.1.2:1345 max fails 3 fail timeout 30s;server 192.168.1.3:9000 down;server 192.168.1.4:9000 backup;}location @php {fastcgi passincludefastcgi param}php-fpm;fastcgi params;SCRIPT FILENAME/var/www/php/index.php;
Semi dynamic backends
upstream php-fpm {server unix:/var/run/php-fpm.sock;include upstreams/*.conf;}location @php {fastcgi passincludefastcgi param}php-fpm;fastcgi params;SCRIPT FILENAME/var/www/php/index.php;
Keep in touch
upstream php-fpm {server unix:/var/run/php-fpm.sock;include upstreams/*.conf;keepalive 10;}location @php {fastcgi passphp-fpm;fastcgi keep conn on;includefastcgi params;fastcgi param SCRIPT FILENAME}/var/www/php/index.php;
O oad Logging
location @php {fastcgi passphp-fpm;fastcgi keep conn on;includefastcgi params;fastcgi param SCRIPT FILENAME/var/www/php/index.php;mirror @logging;}location @logging {fastcgi passlogger-pool;fastcgi param SCRIPT FILENAME /var/www/php/log.php;includefastcgi params;fastcgi param X-Original-Url request uri;}
location @php {fastcgi passfastcgi paramincludephp-fpm;SCRIPT FILENAMEfastcgi params;/var/www/php/index.php;mirror @logging;mirror request body off;}location @logging {fastcgi passlogger-pool;includefastcgi params;fastcgi param SCRIPT FILENAME /var/www/php/log.php;fastcgi param X-Original-Url request uri;}
Who handles errors?
server {errorpage 404 /error/404.html;location @php {fastcgi passfastcgi paramincludephp-fpm;SCRIPT FILENAMEfastcgi params;fastcgi intercept errors on;}location /error/ {root /var/www/errors;}}/var/www/php/index.php;
map http accept language lang {default en; de de;# .}server {errorpage 404 /error/ lang/404.html;location @php {fastcgi passfastcgi paramincludephp-fpm;SCRIPT FILENAMEfastcgi params;fastcgi intercept errors on;}location /error/ {root /var/www/errors;}}/var/www/php/index.php;
More fun with maps
More fun with mapsAlso known as API versioning
map accept header backend {default ‘unix:/var/run/app v1.sock’;‘application/vnd.some-site.v2 json’ ‘unix:/var/run/app v2.sock’;‘application/vnd.some-site.v3 json’ ‘192.168.1.1:9000’;}server {location @php {fastcgi pass backend;}}
map accept header backend {default ‘unix:/var/run/app v1.sock’;include /var/www/versions/*.conf;}server {location @php {fastcgi pass backend;}}
server {location / {try files uri uri/ @new;}location @new {# .fastcgi intercept errors on;recursive error pages on;error page 404 @old;}location @old {# .}}
Sane Downloads
class DownloadQuery {// .public function execute(): Response {if (! this- acl- isAccessGranted( this- file) {return new AccessDeniedResponse();}return new DownloadResponse( this- path . '/' . this- file);}}
class DownloadQuery {// .public function execute(): Response {if (! this- acl- isAccessGranted( this- file) {return new AccessDeniedResponse();}return new DownloadResponse( this- path . '/' . this- file);}}class DownloadResponse implements Response {// .public function send() {header('X-Accel-Redirect: ' . this- file);}}
class DownloadQuery {// .public function execute(): Response {if (! this- acl- isAccessGranted( this- file) {return new AccessDeniedResponse();}return new DownloadResponse( this- path . '/' . this- file);}}class DownloadResponse implements Response {// .public function send() {header('X-Accel-Redirect: ' . this- file);}}
Sane large file uploads
server {location /upload {limit except POSTclient body temp pathclient body in file onlyclient body buffer sizeclient max body size{ deny all; }/var/www/data/uploads;on;1024K;10G;fastcgi pass request headersfastcgi pass request bodyfastcgi ignore client abortfastcgi param X-UPLOAD-FILE}}on;off;on; request body file;
// .let file formElement.querySelector('input[type file]').files[0];let xhr new XMLHttpRequest();xhr.open('POST', '/upload', true);xhr.setRequestHeader('X-Original', file.name);xhr.send(file);// .
Tweaking FPM defaults
[www]pm staticpm.max children 10pm.max requests 500
[www]pm staticpm.max children 10pm.max requests 500slowlog /var/log/php-fpm/ pool.log.slowrequest slowlog timeout 1s
Configure Opcache
opcache.max accelerated files 20000opcache.memory consumption 512
opcache.max accelerated files 20000opcache.memory consumption 512opcache.validate timestamps 0opcache.file update protection 0opcache.save comments 0
opcache.max accelerated files 20000opcache.memory consumption 512opcache.validate timestamps 0opcache.file update protection 0opcache.save comments 0opcache.preload /path/to/preload.php
Make Sessions fast
Make Sessions faster
session.probability 0
session.probability 0session.save handler redissession.save path unix://var/run/redis.sock?persistent 1
session.probability 0session.save handler redissession.save path unix://var/run/redis.sock?persistent 1session.save path tcp://10.0.0.1:6379?persistent 1
Filter all the things?
location /img-low/ {alias /var/www/public/img/;image filter resize 150 100;error page415 @empty;}location @empty {empty gif;}
location /feed/ {proxy pass http://feed-server/atom;xslt stylesheet /var/www/xsl/atom.xsl;}
JavaScript!
js include path/to/switch.js;js set current select pool;server {// [.]location @php {fastcgi passincludefastcgi paramfastcgi param}}unix:/var/run/php-fpm/ current.sock;fastcgi params;REQUEST URI document uri;SCRIPT FILENAME /var/www/php/bootstrap.php;
js include path/to/switch.js;js set current select pool;server {// [.]location @php {fastcgi passincludefastcgi paramfastcgi param}unix:/var/run/php-fpm/ current.sock;fastcgi params;REQUEST URI document uri;SCRIPT FILENAME /var/www/php/bootstrap.php;}function select pool() {return 'www';}
Or Lua!
server {location @php {access by lua file switch.lua;fastcgi passincludefastcgi paramfastcgi param}}unix:/var/run/php-fpm/ current.sock;fastcgi params;REQUEST URI document uri;SCRIPT FILENAME current/runtime/bootstrap.php;
ngx.var.current 'www';return
Single Sign On with Lua
local uuid ngx.var.cookie uuid;if not uuid thenngx.redirect('/login');endlocal redis require "resty.redis"local red redis:new()red:connect("127.0.0.1", 6379)local res, err red:get(uuid)if res ngx.null thenngx.redirect('/login');endngx.header["uuid"] nilngx.req.set header("X-UUID-INFO", uuid);ngx.req.set header("X-USER-INFO", res);return
Sticky session
local sid ngx.var.cookie PHPSESSID;local redis require "resty.redis"local red redis:new()local keys {'default'}if sid thenkeys[2] sidendred:set timeout(100)local ok, err red:connect("127.0.0.1", 6379)local res, err red:mget(unpack(keys))if (res[2] ngx.null) thenres[2] nilendif sid and not res[2] thenred:set(sid, res[1])endngx.var.current res[2] or res[1]return
Thank you https://thephp.cc arne@thephp.cc @arneblankerts
Optimizing NGINX & PHP-FPM — From Beginner to Expert to Crazy International PHP Conference Fall 2019 - Munich. Arne Blankerts Co-Founder, The PHP Consulting Company. Basics. location / {root /usr/share/nginx/html; index index.html index.htm;} location \.php {root html;