Nginx and PHP-FPM Configuration and Optimizing Tips and Tricks - Comment Page: 1

I wrote before a guide Howto install Nginx/PHP-FPM on Fedora 20/19, CentOS/RHEL 6.5/5.10, but this guide is just installation guide and many cases Nginx and PHP-FPM basic configuration is good enough, but if you want to squeeze all the juice out of your VPS or web server / servers and do your maintenance work little bit easier, then this guide might be useful. These tips are based entirely on my own experience, so they may not be an absolute truth, and in some situations, a completely different configuration may work better. It's also good to remember leave resources for another services also if you run example, MySQL, PostgreSQL, MongoDB, Mail server, Name server and/or SSH server on same...

160 comments on “Nginx and PHP-FPM Configuration and Optimizing Tips and Tricks - Comment Page: 1

1 2 3 6
    1. I found my way here googling to get to your VirtualBox post (also well done). I’ve been using php-fpm and nginx for some years now and I do some of these things but some are new.

      Very nicely done and well-presented. I just wanted to say thanks.

      Reply
      • Thanks Chris!

        I have also used Nginx and PHP-FPM (earlier FastCGI) setup long time on my testing environments, now I’m gradually transferring all production web servers to use Nginx and PHP-FPM instead Apache and PHP. Nowadays Nginx and PHP-FPM is excellent choice for everyone who wants handle even massive traffic with good and cheap Virtual Private Servers (VPS). Some cases configuration is even easier than Apache configuration.

        Very nice to hear that you found even something new on this guide and later I will add more tips, when I have some good ideas. ;)

        Reply
    2. Do I need separate linux users (useradd …) for this part:
      user = site
      group = site
      ?

      Great tutorial, thanks! I have already setup a couple of things according to your post.

      Reply
      • Hi Nader and thanks!

        This is just example to show how powerful PHP-FPM Pools are, so you could of course use existing users and groups, example nginx user and nginx group or apache user and apache group.

        This example use totally separate Linux users and groups, because i.e. those pools users / groups access could be limited just their own directories. This is much more secure way if you have multiple totally separated sites. One site security issue does not affect whole system and other sites, because all sites are running by different users with very limited permissions.

        Reply
        • But any user/group defined in a PHP-FPM Pool must exist as a user account in Linux?

          Reply
          • Hi Thomas,

            Yes, user and group must exist on Linux system.

            Reply
            • Which files must then be owned by this specific user defined in the pool?
              Only the pool-configuration-file?
              Or all files of the relevant service in /var/www (or /usr/share/nginx/www), e.g. ownclowd?
              In other words: which files will be accessed by the user account defined in the pool-configuration?

              THX

              Reply
              • Hi Thomas,

                All files of the service (like /var/www/example1) must be owned by specific user. Configuration files are accessed/used only by PHP-FPM process.

                Reply
    3. […] This is just very simple basic configuration, but if you want configure and optimize Nginx and PHP-FPM then check following guide, Nginx and PHP-FPM Configuration and Optimizing Tips and Tricks […]

      Reply
    4. Hi, great tutorial, I really love the setup here. I have one question tho, and it is also regarding users and security.

      On this setup you have different users: site, forum, blog. These will be users with limited capabilities, with an eye on security.

      Now my question is, how can you manage this in a real system. How would you go about on editing the files for the different users. If you have a user that you use to login, let’s says www-user, how can that user edit the files that are owned by users: site, forum, blog.

      If you use a remote program that can not sudo such as winscp on windows then you are pretty much stuck I guess. Or is there a way around this?

      I assume here that the users site, forum, blog do not have login permission.

      Reply
      • Hi Saif Bechan nice to see you here :)

        Here, these users can be, for example two types. Users who have access only to the own directories without login permission or users who have the login permission only to the “chrooted system”, like virtual hosting setups.

        If you want modify all those sites with www user then you something like following setup (this, is just theory / example):

        1. Create users blog, site, forums with nologin

        2. Create www user with login permission

        3. Add www to blog, site and forums groups

        4. Directory structure could look following:

        
        drwxrwxr-x.  2 blog   www  4096 Dec 26 12:40 blog
        drwxrwxr-x.  2 forums www  4096 Dec 26 12:40 forums
        drwxrwxr-x.  2 site   www  4096 Dec 26 12:40 site
        

        If I run multiple pools with different users, then I normally use root user to modify files. This is theoretical example, which I did on /tmp directory and permissions should work nicely… :)

        Reply
        • I’ve been using a similar separate user per site setup for each of my python based sites and found your article whilst looking for a similar way to do this with php, thanks.

          One nice trick is to use setgid on your site directories. If you use setgid on a directory all files and subdirectories inherit its group. So, my site specific directories are all owned by the www user with which I log in (meaning I can edit files without sudo) but setgid ensures all files have a group which is site specific.

          mkdir site

          # set owner to www & group to site
          sudo chown www:site site

          # make sure the group can write to the directory
          sudo chmod g+w site

          # setgid on the site directory
          sudo chmod g+s site

          It also helps to set your umask to 002 in your ~/.profile so that files you create group writable by default.

          I’d be interested to hear your thoughts on this setup.

          Reply
    5. Great post! Don’t forget to enable APC and memcache if you really want to get top speeds. You can also set a reverse proxy in nginx for PHP requests (which means nginx caching PHP requests if possible):

      Inside location:

      fastcgi_cache nginxcache;
      fastcgi_cache_valid any 5m;

      Inside http

      fastcgi_cache_path /tmp/nginx_cache levels=1:2 keys_zone=nginxcache:50m inactive=1d max_size=400m;
      fastcgi_cache_key “$scheme$request_method$host$request_uri”;

      And by the way, maybe you should look into honeypot technique for preventing spam submissions :)

      Reply
      • Hi Ashraf,

        Thanks for nice Nginx reverse proxy tip :) If you have time, you can write more detailed guide, with some full config on If !1 0 forums. I add link with description to your guide of course. :)

        I am thinking of writing own instructions about APC, because it works of course also with other HTTP servers example with Apache. It’s not just Nginx and PHP-FPM related stuff. And I already have Memcache guide… :)

        I actually have honeypot on forums section, but current technique is just totally zero spam technique, but yes I know, it might be irritating…maybe I should change it… :D

        Reply
    6. Hello,

      I’m trying to run with nginxcp, how to create single account don’t want to use nginx

      thanks

      Reply
      • Hi Dedi,

        My apologies, but I do not quite understand your question? Could you try to explain more specific what you are trying to do and what is the problem?

        Reply
    7. Great article, thanks for putting all these tips together!

      One thing that’s not clear to me is how to direct a PHP application to actually use the PHP-FPM pools you’ve provided for it?

      Reply
      • Hi DeltaHF,

        If I understood your question correctly…

        When you create PHP-FPM pools, let’s say you have 3 pools pool1, pool2, pool3 which listens 127.0.0.1:9000, 127.0.0.1:9001, 127.0.0.1:9002:
        1. Create virtual host where you pass PHP requests to pool1 (127.0.0.1:9000)
        2. Create virtual host where you pass PHP requests to pool2 (127.0.0.1:9001)
        3. Create virtual host where you pass PHP requests to pool3 (127.0.0.1:9002)
        4. Create virtual host where you pass PHP requests again to pool2 (127.0.0.1:9001)
        5. …

        Did this answer your question? :)

        Reply
      • Thanks, JR! Yes, I was overlooking the address:port number defined by fastcgi_pass in the Nginx configuration file and I think that disconnect was confusing me.

        I have a blog at / and a message board at /forum on my site. So, if I want the forum to run in its own PHP-FPM pool, would I define a unique fastcgi_pass in a location block like so (assuming the pool is already properly defined, of course)?


        location /forum {
        fastcgi_pass 127.0.0.1:9001;
        ..
        }

        Would this correctly override the “default” port defined in my general “location ~ \.php$ {…}” block as I would expect?

        Reply
        • You are welcome! :)

          Yes, you could use this almost that, but you can’t override any default ports, so you have use little bit different setup…example something like following.

          Separated php-fastcgi.conf file:

          
          fastcgi_index   index.php;
          include         fastcgi_params;
          fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
          fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
          
          
          location /forum {
          fastcgi_pass 127.0.0.1:9001;
          include php-fastcgi.conf;
          }
          

          This is just idea how it could works (not working example)…normally I use different PHP-FPM pools only with different virtual hosts.

          Please let me know if you need more help, or did you get idea? :)

          Reply
    8. Hi JR,

      I try to use fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
      but when I uncomment it in the browser I get 502 Bad Gateway.

      What should I do?

      Thank you!
      Elaidon

      Reply
      • Hi Elaidon,

        How is your PHP-FPM pool configured what you try to use?

        Reply
    9. Hi, Thanks for your blog post it is very informative.

      I just want to ask one question. How can I set a timeout for the php processes? sometimes one of the php-fpm child is using too much cpu which makes my server unresponsive. Right now I am restarting php-fpm every hour using cronjobs. But is there a setting in nginx or php-fpm that can solve my problem?

      Reply
      • Hi Gray,

        You can use PHP-FPM pool option pm.max_requests to limit max request per process.

        Default value is 0 (unlimited), but if you setup it example some value between 50-500 then process stops when it’s handled example 200 requests.

        Reply
    10. I was having some problems with my WHMCS on a Fedora NGINX/PHP-FPM installation (based off your instructions). Turns out the PHP sessions directory /var/lib/php/session was owned by “apache” group (assuming an apache install). I had to chgrp apache /var/lib/php/session to get stuff working properly.

      Might be worth mentioning somewhere that the php-fpm package-related perms have to be updated.

      Other than that, great articles and tips. Can’t wait for them to be updated for Fedora 17! ;)

      Reply
      • Hi N,

        Thanks for this info! :)

        Yes I start test and updating all guides for Fedora 17 when Beta/Final is released… ;)

        Reply
    11. Thanks for your tutorial. Again its very useful especially nginx tip #5 and php-fpm tip #2

      All my websites are using nginx + php-fpm + mysql so I can apply your tips on my servers.

      :)

      Reply
    12. Hi, Thanks for your guidelines. It is helpful.

      Can you explain about the PHP-FPM Pools in more details..
      PHP-FPM Tip 3. – PHP-FPM Pools Configuration

      I followed your guidelines to create my second virtual host.
      I name my 2nd host as forums & using different PHP-FPM pools, name forums

      my conf files should be look like this?
      Create the files from the /etc/nginx/sites-available/forums and under the server { } I put in,

      location ~ \.php$ {
      include /etc/nginx/fastcgi_params;
      fastcgi_pass 127.0.0.1:9002;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME /var/www/forums/public_html$fastcgi_script_name;
      }

      AM i right? is this configuration able to use the 2nd PHP-FPM pools?

      Reply
      • Hi woody,

        Your configuration looks perfect! :D

        Your PHP-FPM pool listen localhost port 9002 and then you pass requests to that port…yes you are right and it should use the 2nd PHP-FPM pools. :)

        Reply
    13. Thank you man. Successfully installed nginx. But php_cgi :) Does the difference?

      Reply
      • Hi Ahmet,

        You are welcome! :)

        Reply
    14. Hi JR, Thanks :)
      I need your help to clarify the code below, kinda confuse about the code below,


      location / {
      index index.html index.htm index.php;
      }


      location ~ \.php$ {
      include /etc/nginx/fastcgi_params;
      fastcgi_pass 127.0.0.1:9000;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME /srv/www/testsite.local/public_html$fastcgi_script_name;
      }

      The location / and location ~ \.php$
      What is that actually means?
      Besides that, how do we know, the php-fpm is running on every request from php?
      Is there any tools to test?

      Need your advice. :) really appreciate it ~

      Reply
    15. Hi JR ,

      Thanks for the tips , i am going to try and implement these settings now on our server .

      With the above mentioned settings and below mentioned hardware configs : what kind of load can the server take : approximately how many visitors a minute or per day :

      CentOS 5.7
      NGINX
      8 Gb RAM ( my full ram keeps running out of memory with just 1000 visitors)

      We went live for an hour this morning and we kept crashing with the following error:

      Too many connections to php-fpm. Server is reaching pm.max_children value.

      Then our server admins did a hard reboot on the server , and our drive started getting mounted on read-only mode.

      And then we were forced to run a FSCK ! We are down 8 hours and counting right now.

      Wish we could hire you as consultant to setup our system and let our admins maintain it time to time. If you are up for it , please hit us up on the email mentioned above.

      Reply
      • Hi Karan,

        Do you run just Nginx and PHP-FPM on that server?

        I think that 8 Gb RAM with good network connection and processor(s) should be enough to handle very huge amount of traffic.

        Could you post output of following commands from your server (example to pastebin.com):

        
        cat /proc/cpuinfo
        
        cat /etc/nginx/nginx.conf
        
        cat /etc/php-fpm.conf
        
        cat /etc/php-fpm.d/*.conf
        
        php -i
        
        ## when server running normally ##
        ps aux |grep -e php -e nginx
        
        free -m
        
        grep -e WARNING -e ERROR /var/log/php-fpm/*.log
        

        Let’s check first if I can help you just with seeing this info… ;)

        Reply
          • Thanks Karan,

            Your server looks very good. :)

            Actually Nginx configuration looks good to me (4 worker processes should be enough, but 8 is also okay with your server) and PHP-FPM need some configuration.

            Let’s do some calculation…if you have 8 Gb memory and let’s use now 4 Gb for PHP-FPM. This is a rough estimate, but let’s say that your PHP-FPM processes use 66 Mb RAM (is not so much really I think) and you have 4 Gb RAM to use.
            4096 / 66 = 62.06

            Based on this theory, it should be safe to set:

            
            pm.max_children = 62
            pm.start_servers = 8
            pm.min_spare_servers = 8
            pm.max_spare_servers = 16
            pm.max_requests = 250
            

            And also enable following settings for PHP-FPM:

            
            emergency_restart_threshold 10
            emergency_restart_interval 1m
            process_control_timeout 10s
            

            I recommend you to backup your config before doing anything, if something goes wrong then you can very easy switch back to your original config… :) After config change remember restart PHP-FPM… :)

            You can monitor your php processes with top, htop or even with following command:

            
            watch -n 2 'ps aux |grep php'
            
            Reply
1 2 3 6

Leave a Reply

Your email address will not be published. Required fields are marked *

Close