Professional Documents
Culture Documents
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
@chrismeller
awesome coder. unashamed php lover. dot net developer. mac user. nginx enthusiast. open data
addict. frequent foia filer. @habari cabal member. system admin. nerd.
There have been several fellow members of the Habari community that have decided to switch to
Nginx lately. Knowing that I run Nginx exclusively (and set up and maintain the instance that hosts the
Habari website itself), theyve asked questions from time totime.
Unfortunately, it turns out some of the guides floating around (even some written and publicized by
major hosting companies) are helping users configure things sub-optimally and in some cases
outright wrong. The standard set of config adjustments I use have been assembled from dozens of
places and lots of time, reading, and experimentation. So Im going to try and take you through
setting everything up, from scratch, the rightway.
Ive used these same basic steps to install PHP-FPM and Nginx on a variety of versions of Ubuntu. The
packages and default configs should remain very similar, regardless of your exact version (or even if
youre usingDebian).
Before you install anything new on your box you should always make sure youve updated the list of
available packages and upgraded any that have updatesavailable:
sudoaptitudeupdate
sudoaptitudesafeupgrade
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
1/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
PHP-FPM
Installing
Getting PHP installed is the first step. This is ridiculously simple, youll just need to install the
fpm
php5
package:
sudoaptitudeinstallphp5fpm
Youll also want to install whichever other PHP packages you need for your specific setup. In my
standard production setups, I usually add php5cliphp5curlphp5mcryptphp5mysqlndphp5sqlite .
Accept any dependencies aptitude wants to install. Once its done churning, its time to configure
your PHP-FPM pool to handlerequests.
2/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
after everything else is running I can easily allow up to 5 php-fpm processes. Well go with that
fornow
The main PHP-FPM configuration file is
/etc/php5/fpm/phpfpm.conf
the default version Ive got. We wont be changing anything in here, but note the last line. Any config
files in the
pool.d
pool.d/www.conf
default version I have). As much as I hate editing default files that could change in future versions of
the packages they belong to, theres really no way to avoid ithere.
pool.d
www.conf
changes directly if you like. The only hard advantage I can see in having separate files is that if the
default should be replaced by a future package update, youll throw errors because configuration
values are duplicated across the files. Think of it as a rather harsh safety net ofsorts
All of the
pool.d
config files I use can be found in this single Gist, if you want a single page to
www.conf
and simply comment out (add a ; at the beginning of the line) anything were
going tooverride:
Line 33:
listen=127.0.0.1:9000
Line 91:
pm.max_children=10
Line 96:
pm.start_servers=4
Line 101:
pm.min_spare_servers=2
Line 106:
pm.max_spare_servers=6
3/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Config files are simply INI files, so anywhere you see [www], that means were defining any of the
settings that follow as belonging to the wwwpool.
ping.conf
If you ever need to simply make sure that php-fpm is alive and handling requests, there is a special
ping URL you can visit that will simply return pong. This defines what path php-fpm will look for
ping requests on, well actually make it work (and limit it to any particular vhosts we like) later when
we configureNginx.
1
[www]
ping.path=/ping
gistfile1.inihostedwithbyGitHub
viewraw
processes.conf
Heres where we define exactly how many processes php-fpm is allowed to spawn. Ive added
comments above each line explaining what theydo.
1
[www]
;atanytime,therecanbenomorethan5childprocesses
;ifyouknowhowmuchmemoryeachprocessconsumesregularly
;andhowmuchfreememoryyouhaveonyoursystem,thisishow
;youseta"hardlimit"ontheamountofmemoryphpfpmwillbeabletoconsume
pm.max_children=5
7
8
;whenphpfpmfirststarts,howmanyprocessesshould
;itimmediatelygeneratetohandlerequests?
10
;whenyourestartphpfpm,theremaybeaninfluxofrequests.
11
;spawninganewprocesscantaketime(albeitverysmall),sowewant
12
;togoaheadandhavethismanyreadytogo
13
pm.start_servers=2
14
15
;iftherearenorequestscurrently,howmanyspare
16
;processesshouldwealwaysmakesuretokeeparound?
17
;again,thereisadelayinspawningnewprocesses,
18
;sohavingafewalwaysreadytogoisagoodidea.
19
;theoffsetisthattheywillbetakingupmemorythatyoursystem
20
;mightotherwisebeabletouseforotherthings
21
pm.min_spare_servers=1
22
23
;theinverseoftheformer.ifthere'snothinggoingon,
24
;howmanyspareprocessesareweallowedtokeeparound?
25
;again,fewermeansmorememoryonthesystemforotherthings,
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
4/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
26
;butmoremeanslessofadelayifaninfluxofrequestscomesin
27
pm.max_spare_servers=3
viewraw
gistfile1.inihostedwithbyGitHub
socket.conf
By default php-fpm listens on a TCP port, just like your web server. This works great if youve got a
cluster of web servers handing requests back to separate servers which handle PHP requests, but on
a single server theres not much point and a Unix socket can be (minorly)faster.
1
[www]
listen=/var/run/php5fpm.socket
viewraw
gistfile1.inihostedwithbyGitHub
status.conf
To go along with our
ping.conf
endpoint, well also enable one for some detailed statistics. This
might not be of much use to you unless youve got some external script scraping it for monitoring or
performance graphing, but it will tell you when php-fpm was last started, how many requests it has
served, the current number of processes, clients in the queue,etc.
1
[www]
pm.status_path=/status
viewraw
gistfile1.inihostedwithbyGitHub
sudo/etc/init.d/php5fpmrestart
togo.
Now its time to get Nginx installed and configured to actually process PHPrequests!
Nginx
Installing
The version of Nginx that comes with Ubuntu can be incredibly outdated. In the past I have always
used the Nginx PPA repository to get more recent versions, but this appears not to be as supported as
it was in the past. Fortunately the Nginx team has an official repo you can addeasily.
These instructions start on the Nginx wiki, but can use some more user-friendlydetails.
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
5/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
First off, Nginx signs their packages with their own PGP key. Before
you need to import it:
apt
wgetOhttp://nginx.org/keys/nginx_signing.key|sudoaptkeyadd
Then you need to figure out which release codename you are using so you get the right version of
Nginx for your system. This varies between distros,so
Ubuntu
In Ubuntu run
cat/etc/lsbrelease
DISTRIB_CODENAME
value.
Debian
In Debian run
cat/etc/osrelease
VERSION
sudovim/etc/apt/sources.list.d/nginxstable.list
The lines you add vary depending on whether you are using Debian orUbuntu.
Ubuntu
For Ubuntu boxes, add the following two lines, substituting your codename where it saysprecise:
debhttp://nginx.org/packages/ubuntuprecisenginx
debsrchttp://nginx.org/packages/ubuntuprecisenginx
Debian
If youre running Debian, youll need these two lines instead, of course substituting your appropriate
codename forsqueeze:
debhttp://nginx.org/packages/debian/squeezenginx
debsrchttp://nginx.org/packages/debian/squeezenginx
If you had previously installed an old version of Nginx (such as your distros native version) you can
get rid of it quickly using the command sudoaptitudepurgenginxnginxlightnginxfullnginx
extrasnginxcommon
purge
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
6/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Base Configuration
Nginxs default config is much less annoying than PHP-FPMstheres not a single thing we need to
change. Because new versions of Nginx may come with new default configurations, you shouldnt
edit the default /etc/nginx/nginx.conf file.
Instead, you can stick all of your custom modifications in the
we did with the
pool.d
/etc/nginx/conf.d
Again I split everything out into its own distinct configuration file, just so its easier to keep track of
things and find the bits youre looking for if you need to change something down theline.
PHP-FPM
The entire goal of this process is to get PHP working with Nginx, right? Well, here wego
1
upstreamphp{
serverunix:/var/run/php5fpm.socket;
4
5
#makesureindex.phpisfirstinallourvhosts
indexindex.phpindex.htmlindex.htm;
gistfile1.nginxconfhostedwithbyGitHub
index.php
viewraw
More importantly, it sets up a named upstream server that well use to hand all requests for PHP
filesto.
Using the named upstream is very important. Youll have a bunch of vhosts setup, each of which have
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
7/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
to include a location block telling Nginx to hand any requests for PHP files off to PHP-FPM for
processing. If you should change your PHP-FPM config (for example, you need to expand and decide
to put it on its own server) having the single named upstream server means you only have to update
this in one place, rather than in each separatevhost.
Other Tweaks
Now that weve got PHP working, there are still a bunch of other knobs we should turn and settings
we should tweak. Lets run through a bunch of thosequickly.
charset.conf
By default, Nginx does not alter the character encoding of anything it serves. Since we should
definitely be serving everything we possibly can as UTF-8 these days and files tend to come from lots
of different places, the first thing we want to do is make sure any other screwy character sets
areconverted.
The charset directive will not only cause Nginx to re-encode anything that is not in the defined
character set, it will also add it to the ContentType HTTP header so browsersknow.
1
charsetutf8;
gistfile1.nginxconfhostedwithbyGitHub
viewraw
expires.conf
By default Nginx does not modify any of the headers sent with your content. For static resources,
though, one of the first optimizations you should make for any site is to set a far-future
Expiresheader.
The expires directive will do just that foryou.
Most people will try to limit (based on file extension) which files the Expires header gets set on.
Personally Ive never liked this approach - youre pretty much guaranteed to miss something. A bad
analogy would be whitelisting (rather than blacklisting) email providers to avoidSPAM.
So I set the Expires header on everything. Anything that should not be cached for a long period of
time should set its own headers to prevent that. PHP does this on any page in which a session exists
automatically (in other words, most pages where you have to log in and content would be dynamic),
so most people probably dont need to worrymuch.
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
8/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
You can, of course, look up any variety of examples on how to use regex in a location block to limit
based on fileextension.
expiresmax;
gistfile1.inihostedwithbyGitHub
viewraw
gzip.conf
The Nginx Gzip module compresses content before transmission to save on bandwidth. On flakey
mobile connections this can be especiallyimportant.
1
#mostpeopleincludesomethinglikethis.don't.
#checkyourdefaultnginx.conf,it'salreadycoveredinamuchbetterway.
#gzip_disable"MSIE[16]\.(?!.*SV1)";
4
5
#compressproxiedrequeststoo.
#itdoesn'tactuallymatteriftherequestisproxied,westillwantitcompressed.
gzip_proxiedany;
8
9
#aprettycomprehensivelistofcontentmimetypesthatwewanttocompress
10
#there'salotofrepetitionherebecausedifferentapplicationsmightusedifferent
11
#(andpossiblynonstandard)types.wedon'treallycare,westillwantthemincluded
12
#don'tincludetext/htmlitisalwaysincludedanyway
13
gzip_types
14
text/css
15
text/plain
16
text/javascript
17
application/javascript
18
application/json
19
application/xjavascript
20
application/xml
21
application/xml+rss
22
application/xhtml+xml
23
application/xfontttf
24
application/xfontopentype
25
application/vnd.msfontobject
26
image/svg+xml
27
image/xicon
28
application/rss+xml
29
application/atom_xml;
30
31
#increasethecompressionlevel,attheexpenseofadditionalCPU
32
#cpucyclesarecheapvirtuallyeverywherenow,bandwidthnotnearlyasmuch
33
gzip_comp_level9;
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
9/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
34
35
#thedefaultistogziponlyHTTP1.1requests
36
#wewanttogziphttp1.0requests,too,solowerthelevelrequired
37
gzip_http_version1.0;
38
39
#settheVary:AcceptEncodingheadertoforceproxiestostorecompressedanduncompressedversions
40
#perthenginxdocs,abuginIE46willcausethemtonotcacheanythingwiththison
41
#mostpeoplearen'tgoingtocareaboutie6anymore,butkeepthatinmind
42
gzip_varyon;
43
44
#increasethesizeofthebufferswhichholdresponsestomakesurelargercontentcanbecompressed
45
#thismeansthereare16buffersandtheycaneachhold8k
46
#ifyouservealotofridiculouslylargetext(likecombinedCSS)youmightconsideruppingthissl
47
gzip_buffers168k;
48
49
#uptheminimumlengthalittletoaccountforgzipoverhead
50
#thismeansanythingsmallerthan50byteswon'tbecompressed.
51
#thedefaultis20bytes,whichissoootinyit'sawastetocompress
52
gzip_min_length50;
gistfile1.nginxconfhostedwithbyGitHub
viewraw
ssl.conf
If youre going to use SSL, this is a very important one. The default SSL config for Nginx has a number
of potentialweaknesses.
1
#wewanttoenablesslsessionresumptiontoavoid
#havingtostartthehandshakefromscratcheachpageload
#sofirstweenableasharedcache,namedSSL(creative!)thatis10mblarge
ssl_session_cacheshared:SSL:10m;
5
6
#savethingsinthecachefor3minutes
#ifyou'renotmakingarequestatleastevery3minutes,thisisn'tgoing
#toaccomplishanythinganyway
ssl_session_timeout3m;
10
11
#nowwe'regoingtochangeabunchrelatedtoSSLciphersandprotocol
12
#theprimarygoalhereistobemoresecure,andi'vegenerallytriedto
13
#gowiththingsthatcomplywiththeFederalInformationProcessingStandard(FIPS)
14
#setbytheUSgovernmentfornonmilitarygovernmentuse
15
16
#wedon'twanttosupportSSLv3,it'sknowntobeinsecure
17
#FIPS1402compliance,TLS1+only
18
ssl_protocolsTLSv1TLSv1.1TLSv1.2;
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
10/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
19
20
#nowwegothroughacoupledifferentoptionsfortheSSLcipherstosupport,mainlyjustto
21
#giveyouabunchofoptionstopickfrom
22
23
#thisisaveryconcisedefinitionofciphersthatdon'tallowanonymousDHorMD5thebigweaknes
24
25
#ssl_ciphersHIGH:!ADH!MD5:@STRENGTH;
per:https://calomel.org/nginx.html
26
27
#thisisavery(notso)shortlistofverysecureciphersthatmaybeincompatiblewitholderbrows
28
29
#ssl_ciphersECDHERSAAES256GCMSHA384:ECDHERSAAES256SHA384:ECDHERSAAES256SHA:AES256GCMSHA3
per:https://calomel.org/nginx.html
30
31
#thisexcludesinsecureciphersandsortstheothersbystrength
32
#itisBEASTresistant,prioritizingRC4
33
34
#ssl_ciphers!aNULL:!LOW:!MD5:!EXP:RC4:CAMELLIA:AES128:3DES:SEED:AES256@STRENGTH;
per:http://groups.drupal.org/node/179344
35
36
#thisisacombinationofeverythingaboveandopenssldocsverysecure,FIPScompliant,orderedb
37
ssl_ciphers!aNULL:!eNULL:FIPS@STRENGTH;
38
39
#don'tlettheclientdecidewhatcipherstouse,we'vetoldtheserverwhichtoallow
40
ssl_prefer_server_cipherson;
gistfile1.nginxconfhostedwithbyGitHub
viewraw
uploads.conf
Most people have probably had to adjust a couple of INI values for PHP to allow larger file uploads.
Well, now youve got one more thing to adjust. The default Nginx client_max_body_size is 1mb.
Thats too small for most everything these days, so I go ahead and up it to a more reasonable (yet still
memory-conscious)limit.
Yes, this means that if someone tries to attack your site by constantly uploading multiple
simultaneous large files, your system could run out of memory. Lets be realistic: there are probably
dozens of better ways someone whos set on being malicious could interfere with the normal
operation of yoursite.
1
client_max_body_size32m;
gistfile1.nginxconfhostedwithbyGitHub
viewraw
Vhost Config
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
11/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Now that weve got all that stupid stuff out of the way, its time to get a vhost configured so you can
actually start seeing your new site inaction!
All vhosts go in
/etc/nginx/sitesavailable
you should keep a rigid standard. I name all of mine exactly what they are, like
blog.chrismeller.com
server{
#wewanttolistenonport80onallIPsonoursystembothIPv4andIPv6
listen[::]:80;
#ourprimaryservernameisthefirst,aliasessimplycomeafterit.youcanalsoincludewi
server_nameblog.chrismeller.comnew.chrismeller.com;
#whereareoursitefilesstored?
root/media/www/public_html/blog.chrismeller.com/public;
10
#defineouraccessanderrorlogsforthisvhost
11
access_log/media/www/public_html/blog.chrismeller.com/logs/access.log;
12
error_log/media/www/public_html/blog.chrismeller.com/logs/error.log;
14
#veryimportant,phpwon'tworkwithoutthisitsetsabunchoftheserver
15
#valuesthatitexpects
16
includefastcgi_params;
18
#weareverysimpleanyrequeststhatdon'tmatchoneofthelaterlocationblockswe
19
#definewillbematchedbythisone
20
location/{
22
#forhabari,iwanttoredirectanyrequestsfortheadminorloginpages
23
#tothesslversions,toprotectanypotentialsensitiveinput
24
rewrite^/(admin|auth)(.*)https://$host$request_uri?;
26
#themagic.thisistheequivalentofallthoselinesyouuseformod_rewriteinApa
27
#iftherequestisfor"/foo",we'llfirsttryitasafile.thenasadirectory.an
28
#we'llassumeitssomesortof"clean"urlandhandittoindex.phpsoourCMScanw
29
try_files$uri$uri//index.php$is_args$args;
31
#$is_argswillbe'?'ifthereisaGETstring,or''ifthereisn't
32
#$argsisobviouslythentheGETstring,or''ifthereisn'tone
33
35
#rememberthatPHPFPMstatusURLwesetup?wewanttosupportitforthis
36
#vhost.soiftherequestisfor/status,handthatbackto
37
#PHPusingournamedupstreamserver
38
location/status{
13
17
21
25
30
34
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
12/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
39
fastcgi_passphp;
40
42
#thisisidentical,butforthepingURLwesetup
43
location/ping{
44
45
47
#andfinally,themagicthatmakesPHPwork.ifthefilebeingrequestedendsin".php"
48
#it'ssomethingthatPHPFPMshouldprocess,sohandittoournamedupstreamserver
49
location~\.php${
50
51
52
41
fastcgi_passphp;
46
fastcgi_passphp;
gistfile1.nginxconfhostedwithbyGitHub
viewraw
What about an SSL vhost? Well, its very similar, so Ill only point out thedifferences.
1
server{
#thesameasfornonssl,exceptweindicatethatwhenlisteningonport
#443,itshouldusessl
listen[::]:443ssl;
server_nameblog.chrismeller.comnew.chrismeller.com;
#specifythecertificate(chain)andkeyfiletobeusedforthisvhost
ssl_certificatessl/chrismeller.com.2012.pem;
ssl_certificate_keyssl/chrismeller.com.2012.key;
11
#iuseadifferentdirectoryasamaterofpractice,andjust
12
#createasymlinktothenormalnonssl"public"directorywhentheyarethesame
13
root/media/www/public_html/blog.chrismeller.com/ssl;
15
#notethedifferentlogsforsslandnonssl.norealreason,it'sjustconvenientforme
16
access_log/media/www/public_html/blog.chrismeller.com/logs/ssl.access.log;
17
error_log/media/www/public_html/blog.chrismeller.com/logs/ssl.error.log;
includefastcgi_params;
21
location/{
22
#theonlyotherdifferenceisthati'mnotredirectingadmin
23
#andloginpageswe'realreadyonssl
24
try_files$uri$uri//index.php$is_args$args;
25
10
14
18
19
20
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
13/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
26
27
location/status{
28
29
31
location/ping{
32
33
35
location~\.php${
36
37
38
fastcgi_passphp;
30
fastcgi_passphp;
34
fastcgi_passphp;
viewraw
gistfile1.nginxconfhostedwithbyGitHub
And for the record, I name them very similarly to the non-SSL vhosts, but keep them in separate files
so they can be enabled and disabled individually and I can tell at a directory glance which ones
support SSL:
blog.chrismeller.comssl
40Comments
ChrisMeller
Recommend 5
Share
Login
SortbyBest
Jointhediscussion
phillip 2yearsago
Havinganexplanationforjustabouteverysinglelinemadethispostsupervaluabletome.
Thankyouforthis.
10
Reply Share
JoseVega>phillip ayearago
Metoo.Imsettingupmyvpsandthispostisgold.
Reply Share
miklb 2yearsago
Justanfyi,seemssomeoneonthephpfpmpackagemusthavereadthispost,asthe
defaultsforwww.confmax_children,startservers,andmin/maxspareserversarethe
sameasyourtutorial.Italsodefaultstolisten=/var/run/php5fpm.socket
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
14/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Thanksagainforwritingthisup,wasahandyreminderforsettingupanewVPS.
2
Reply Share
miklb>miklb 2yearsago
AcoupleofnotessinceIcommented:
*Ineededtoadd`fastcgi_paramSCRIPT_FILENAME
$document_root$fastcgi_script_name`tofastcgi_params.Otherwise,Iwasgetting
ablankpageonphppageswithzeroerrorsand200statusontheaccesslog.Took
alongtimetotrackthatonedown.
*Also,itseemsthelistenshouldbe/var/run/php5fpm.sock,notsocketanymore.
NotsureiftheyaresynonymousbutIuseditandeverythingisworkingnow.
2
Reply Share
chrismeller
Mod >miklb
2yearsago
CanyoucheckwhatOS(andversion)andversionofNginxyou'reusing
thatyouhadtoaddSCRIPT_FILENAME?Ihaven'thadtoaddthatmanually
inquiteawhile.
Thesocketextensionhasnospecialmeaningbeyondlettingyouknowit'sa
socketwhenyoulistdirectorycontents.Ifthedefaulthaschangedyoucan
changeeitheritoryourNginxconfig,it'sallgood.
Reply Share
miklb>chrismeller 2yearsago
MycurrentversionofNginxis1.4.4.1~wheezy.Phpinfoshow
systemDebian3.2.412+deb7u2i686.
Reply Share
joseheribertoperezmagaa>miklb 10monthsago
Ihadthesameproblem,Ihaveubuntu14withnginxversion:
nginx/1.6.2
I'musinginthesocket.conffile:
[www]
listen=/var/run/php5fpm.sock
insteadof
[www]
listen=/var/run/php5fpm.socket
andthatdidthejob
btwthanksforthisincredibletutorial
Reply Share
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
15/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
JamesMorris 2yearsago
Thanksforagreatexplanationandallthecomments.
1
Reply Share
PHPGuru 2yearsago
HeyChris,thisguidewasextremelyhelpful.IusedthedotdebreposwithDebianSqueeze
andnowhaveLEMPupandrunningwithnginx1.4.1,php5.4.16php5fpm&MySQL
5.5.31.Tookaboutanhour,andI'veonlyworkedwithApachebeforetoday.Nicework!
1
Reply Share
mrrssy 6monthsago
thankyouforthissuperexplaineddocumentation!
Reply Share
Thomas 10monthsago
HiChris,
whatdoyouthinkabouttheusage/configurationofdeditactedsocketsforeach
subdomain:
upstreamphp{
serverunix:/var/run/php5fpm<subdomain1>.socket
}
upstreamphp{
serverunix:/var/run/php5fpm<subdomain2>.socket
}
Reply Share
chrismeller
Mod >Thomas
10monthsago
Ifyou'vegotmultipleFPMpools(saytoprotecttheresourcesofonesitefrom
another)thenyouwouldlogicallyhavemultiplelisteners(eithersocketsorports)
thatNginxwouldneedtorelaytrafficto.Sointhatcaseyou'ddefinitelyneed
multipleupstreams.
OneerrorIseeinyourexampleisthatyou'venamedboththeupstreams"php".
Rememberthatthoseneedtobeuniqueaswell,soNginxknowswhichupstream
you'retellingittouse.
Nowtherealquestionis...shouldyoudothis?Idon't,butthat'sbecauseIruna
verysmallVPSthatonlyhostsmyownpersonalsites.Ifoneofthemgets
clobberedit'sprobablygoingtotaketheentireserverdownanyway,sothere'sno
pointinaddingtheextraoverheadtousemultipleFPMpools(sinceeachpoolwould
haveitsownsetofprocesseslisteninganditsownpm.min_spare_servers).
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
16/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Iprobably*would*recommendusingmultiplepoolsifyou'rehostingindependent
clientsites,though.Givingeachonetheirownsetofprocessescandefinitelyhelp
makesurethatthey'relessvulnerabletoonesitekillingeverything.Justremember
thatallthat"howmanyprocessescanIrunwiththeamountofRAMIhave?"math
willgetalotmorecomplicated.
Youwouldalsoobviouslyneedmultipleupstreams(thoughthey'dbeusingports,
notsockets)ifyouhadNginxsittinginfrontofmorethanonebackendserverthat
ranFPM(ratherthanrunningFPMonthesameboxasNginx),butthatopensupa
wholedifferentcanofwormswewon'tgointo.
Reply Share
Locke 2yearsago
thisisagreathowto,thanks,butI'mgetting:
[02May201418:20:11]ERROR:AnanotherFPMinstanceseemstoalreadylistenon
/var/run/php5fpm.sock
[02May201418:20:11]ERROR:FPMinitializationfailed
doyouknowwhythisishappening????
Reply Share
chrismeller
Mod >Locke
2yearsago
You'vealreadygotaninstanceofFPMrunning,then.Running`psaux|grepiphp`
shouldshowyou.Iwouldn'tbeabletotellyouhowanotherisrunning,butthat's
yourproblem.
Reply Share
Locke>chrismeller 2yearsago
Oh!!!,nowIsee,thisisbecauseIhavealotofdomainsintheserver.lotof
sitesavailablethatarerunningphpfpmmaybethatismymainproblem..
Reply Share
temuri 2yearsago
Thanksforthewriteup.
HowdoyouhandleredirectstoSSLinyournginxconfig?
Reply Share
chrismeller
Mod >temuri
2yearsago
IusearedirecttoSSLintwodifferentwaysdependingonthegoal.
Inoneinstance,IwantallrequeststoenduponSSL.Sofor
http://www.example.comeverythingshouldendupathttps://www.example.com.In
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
17/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
http://www.example.comeverythingshouldendupathttps://www.example.com.In
thatcase,IsimplysetupabarebonesvhostforthenonSSLversion:
https://gist.github.com/chrism...
Ifyou'regoingtoalwaysredirectallrequeststoSSL,youshouldalsolookat
includingtheStrictTransportSecurityheadersomodernbrowsersnevertrytohit
theplaintextversionanyway.
IfthereareonlycertainrequeststhatIwanttoensureareSSLprotected,likethe
loginandadminpagesofaCMSwherepasswordsmightbeseen,youcanredirect
onlythoserequests:https://gist.github.com/chrism...
HerethevhostisotherwisethesameastheexampleIgaveintheguide,butifthe
pathstartswithadminorauthwewanttomakesurethoseareSSLrequests.
Reply Share
m4nuco 2yearsago
ThanksChris,Awesomearticle.Ididn'tgetonethingthowherewouldyouputtheupstream
phpserverthingy?Init'sownfile?
Reply Share
chrismeller
Mod >m4nuco
2yearsago
Shortanswer:Iputitinconf.d/php.conf
Longanswer:Anywherethatnginxwillincludeit.Inmyexamplesalltheconfigfiles
arein/etc/nginx/conf.d/becausethosearetheconfigfilesincludedbydefault.It
doesn'tactuallymatterwhatyounamethefile,justsomethingthatyouwillrecognize
(phpseemedobvioustome).
1
Reply Share
m4nuco>chrismeller 2yearsago
OkthanksChristhatwashelpful.
Notethoihadsameproblemasmiklb,neededtoaddfastcgi_param
SCRIPT_FILENAME$document_root$fastcgi_script_nameinordertogetit
towork.(Ubunutu12.4,nginx1.4.4).Youprobablyshouldaddanoteabout
thatinyourpost
Reply Share
KJ 2yearsago
Thanksfordoingthis...Clearedupalotofquestions(fears)Ihadbeforetakingtheleapinto
selfmanagedVPS
Reply Share
cakuki 2yearsago
Asthearticleitselfisarealmasterpiece,my"justonething"isaboutphpfpmpool
configurationseparation.Aspooldirectoryintendedtocontainmorethandefaultwwwpool
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
18/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
configurationseparation.Aspooldirectoryintendedtocontainmorethandefaultwwwpool
configuration.
Ihavechangedtheincludevaluein/etc/php5/fpm/phpfpm.confto:
include=/etc/php5/fpm/pool.d/*/*.conf
soIhavemywwwconfigurationsseparatedlikepool.d/www/foo.conf.
ThismakesTCPandsocketproxiesavailableindifferentpoolconfigurationswithout
confusion.
Reply Share
chrismeller
Mod >cakuki
2yearsago
Thanks,cakuki!That'sanicelogicalseparation,ifyouneedbothtypesoflisteners!
Reply Share
tushar 2yearsago
Greattutorial.
AfterIupgradednginxserverfrom1.1.19to1.4.4andmadetheabovechanges,I'mnow
gettingError503.Whatmightbethecause?
Reply Share
chrismeller
Mod >tushar
2yearsago
Blindly,offthetopofmyhead,with0details?Ihavenoclue.Likeanytimeyou're
troubleshooting,checkyourerrorlog.
Themainnginxlog(asopposedtothevhostspecificonesyoudefineineach
config)isusually/var/log/nginx/error.log,whichmaycontainmoredetails.
1
Reply Share
tushar>chrismeller 2yearsago
2013/12/0908:35:48[crit]14861#0:*7415connect()tounix:/var/run/php5
fpm.sockfailed(2:Nosuchfileordirectory)whileconnectingtoupstream,
client:127.0.0.1,server:95.85.29.90,request:"GET/HTTP/1.1",upstream:
"fastcgi://unix:/var/run/php5fpm.sock:",host:"livingwithict.com"
2013/12/0909:30:42[emerg]1927#0:bind()to0.0.0.0:80failed(98:Address
alreadyinuse)
2013/12/0909:30:42[emerg]1927#0:bind()to0.0.0.0:80failed(98:Address
alreadyinuse)
2013/12/0909:30:42[emerg]1927#0:bind()to0.0.0.0:80failed(98:Address
alreadyinuse)
2013/12/0909:30:42[emerg]1927#0:bind()to0.0.0.0:80failed(98:Address
alreadyinuse)
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
19/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
alreadyinuse)
2013/12/0909:30:42[emerg]1927#0:bind()to0.0.0.0:80failed(98:Address
alreadyinuse)
2013/12/0909:30:42[emerg]1927#0:stillcouldnotbind()
Reply Share
joseheribertoperezmagaa>tushar 10monthsago
IcanconfirmtheerrorwhatIdidtofixtheerrorjustreplacethe
following:
[www]
listen=/var/run/php5fpm.socket
for
[www]
listen=/var/run/php5fpm.sock
Reply Share
chrismeller
Mod >tushar
2yearsago
ThefirsterrorindicatesthateitherNginxorPHPFPMismis
configured.CheckyourNginxphpupstreamtomakesuretheserver
directiveiscorrect.Morelikely,youdidn'tsetthelistendirectivein
yourPHPFPMpoolconfiguration"socket.conf"inmyguide.
Thelattererrorsaremostlikelybecausethedefaultvhost
configurationincludesanincompatible`listen`directive.Double
checkallyourvhostsandmakesuretheyhavethesame`listen`
directive.
Ifyoucan'tfindtheproblem,moveinto/etc/nginxandrun`grepri
"listen".`,whichshouldshowyoueveryfilethatmightincludethe
problem.
Reply Share
Josh 2yearsago
Idon'tunderstandhowtosetthepm.max_children,pm.start_servers,
pm.min_spare_serversandpm.max_spare_servers...IhaveanIntel(R)Core(TM)i7CPU
920@2.67GHzwith8coresand48GBofRAM.Ihaveset:pm.max_children=1000,
pm.start_servers=245,pm.min_spare_servers=45,pm.max_spare_servers=350(I
wantatleast1000concurrentsusers).ButIhavesomeerrorsayingmethatihavetoo
maneprocesses...What'swrong?ThankyouveryMuch!
Reply Share
chrismeller
Mod >Josh
2yearsago
LikeIsaid,italldependsonexactlywhatyou'rerunning.Youshouldstartofflow,
runyourapplicationforawhile(evenifit'sjustyousteppingthroughitlikeanormal
userforawhile,possiblyoveradayortwo),andthenseehowmuchmemoryeach
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
20/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
phpfpmprocessisoccupyingonyoursystem(`psaux|grepphp`orsimilar).
Afterthat,youneedtodivideouttheamountofRAMyouhaveleftonyourbox
(makesuretoaccountforMySQLoranyotherbackgroundprocessesthatyou'll
haverunning)andfigureoutthenumberofprocessesyoucanreasonably
accommodate.
Withouttheexacterror,Ican'thelpwiththe"toomanyprocesses"erroreither.
Reply Share
DanielSearles 2yearsago
IforgottomentionthatthisisagreatpostandthatIappreciateyouwritingitup.Goodjob!
Reply Share
DanielSearles 2yearsago
`location~\.php${`isasecurityvulnerabilitysinceitallowsanyphpfiletoberunincluding
uploadedfiles.Seethisarticleforamoreindepthexplanation:
https://nealpoole.com/blog/201...
Reply Share
chrismeller
Mod >DanielSearles
2yearsago
Intheexampleheprovides,FPMactuallyunderstandsthattherequestisfor
random.gif,evenifNginxattemptstopasstherequesttoitbasedontheendingof
.php.
Ifyoucheckyourerror.logfileyou'llseearesponsefromFPMalongthelinesof:
Accesstothescript'/whatever/public/random.gif'hasbeendenied(see
security.limit_extensions)
Thesecurity.limit_extensionspooloptionwasaddedinPHP5.3.9anddefaultsto
onlyincludingtheextension.php,preventingexactlythisproblem.Since5.3.9was
releasedalmosttwoyearsago(January,2012)there'saprettygoodbetmostofus
arefine(Ubuntu12.04LTSincludes5.3.10,butifyou'restillrunning10.04LTSyou
mighthaveanissue).
Forsomeinexplicablereasonthisisn'tincludedinthePHPdocumentation,butthe
topcommentonthepagepointsitout:http://php.net/manual/en/insta...
Reply Share
Tecto 2yearsago
Aboutthisbit:
#checkyourdefaultnginx.conf,it'salreadycoveredinamuchbetterway.
#gzip_disable"MSIE[16]\.(?!.*SV1)"
Mydefaultnginxconfigdoesn'tappeartohaveanythingtocoverthis.Canyouclarify?
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
21/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
Reply Share
chrismeller
Mod >Tecto
2yearsago
TheUbuntuandDebiandefaultsI'veseenusuallyhavea`gzip_disablemsie`line,
whichisafasterversionoftheregexpatternmostpeoplestickinthere:
http://nginx.org/en/docs/http/...
Ifyoudon'thaveoneyoucansimplyadd:gzip_disablemsieinyourgzip.conf.
Reply Share
VilhjlmurMagnsson 2yearsago
Anyideasonhowtofixthe"Filenotfound"issuewhenusinguserdirandvhostsforphp?
Reply Share
RieksVisser 2yearsago
Veryconciseandwellwritten,thankyou!ThishelpedmealotinmovingfromApache2to
Nginx.IcanalsoconfirmthatyourguideworksjustaswellonaDebian7(Wheezy)server.
TwothingsIdidencounterwere:
1.InstallingnginxfromPPAdidn'tworkoutforme,perhapsIwasabitimpatient.Intheend,
Iwentwithasimpleaptgetinstallnginx.OnanupdatedWheezythisendedupgivingme
nginx/1.2.1.Notquitebleedingedge,butrecentenough.
2.Rule3inthevhostconfigresultedinan'addressalreadyinuse'error.Afixwaseasily
found:http://stackoverflow.com/quest....Inshort:listeningtoport80forbothipv4andipv6
inoneruleconflictswiththenginxdefaultconfig.
Reply Share
chrismeller
Mod >RieksVisser
2yearsago
I'veactuallyjustrecentlystoppedusingthePPA.Itlookslikeit'snotbeingupdated
asregularlyasitusedtobe...ButtheofficialNginxDebian/Ubunturepository
worksfine.I'llupdatethatsoon.
Asforthedefaultconfig,you'reprobablycorrect.Imayhaveaccidentallyskipped
overremovingthatbitfromthedefaultconfig.That'swhathappenswhenyou're
writingaguideafterthefact!I'mintheprocessofmigratingsomesitestoanewbox
now(it'sthere,Ijusthavetogetaroundtoconfiguringit!),soI'llbesuretogive
everythinganotherrunthroughasIdoandmakeanyneededupdates.
Thanksverymuchforthefeedback!
22/23
11/4/2015
ConfiguringandOptimizingPHPFPMandNginxonUbuntu(orDebian!)|ChrisMeller
http://blog.chrismeller.com/configuringandoptimizingphpfpmandnginxonubuntuordebian
23/23