Installing nginx & PHP-FPM securely on CentOS

I won’t go into the reasons why you should install nginx, if you’re here, you’ve already decided.
Here’s how I installed nginx and PHP-FPM on CentOS.

Firstly, I got the latest PHP 5.2 tar ball, 5.3 sucks, then the PHP-FPM patch and finally the latest nginx.

[codesyntax lang=”bash”]
wget http://uk3.php.net/get/php-5.2.17.tar.gz/from/uk.php.net/mirror
wget http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz
wget http://nginx.org/download/nginx-0.9.5.tar.gz

 

Optional: I installed MySQL server aswell. You don’t have to.

[codesyntax lang=”bash”]
yum install mysql-server
/etc/init.d/mysqld start

If you’re on CentOS, don’t forget to finish the MySQL installation

[codesyntax lang=”bash”]
/usr/bin/mysql_secure_installation

Install PHP

Next, some pre-requisites for the PHP & nginx installs. You may not need them all depending on how you configure PHP. Delete/add to suit.

[codesyntax lang=”bash”]
yum install libxml2-devel bzip2-devel curl-devel libjpeg-devel libpng-devel libX11-devel gd-devel libc-client-devel libmcrypt-devel mysql-devel mhash-devel libevent-devel libtool-ltdl-devel

Now some pre-requisites for building the souce

[codesyntax lang=”bash”]
yum install patch gcc make libtool-ltdl libtool

Lets build PHP

[codesyntax lang=”bash”]

tar zxpfv php-5.2.17.tar.gz

gzip -cd php-5.2.17-fpm-0.5.14.diff.gz | patch -d php-5.2.17 -p1

cd php-5.2.17

./configure  –enable-fastcgi –enable-fpm –with-mcrypt –with-zlib –enable-mbstring –disable-pdo –with-mysql –with-curl –disable-debug –disable-rpath –enable-inline-optimization –with-bz2 -with-zlib –enable-sockets –enable-sysvsem –enable-sysvshm –enable-mbregex –with-mhash –enable-zip –with-pcre-regex –with-freetype-dir –with-jpeg-dir –enable-zend-multibyte –with-gd –with-libdir=lib64
make
make install

For kicks, we’ll install the MemCache and APC caching extensions, we’ll use them some time.

[codesyntax lang=”bash”]
pecl install memcached apc

Then, copy the php.ini file to its new home, don’t be tempted to copy it elsewhere otherwise it’ll never find itself.

[codesyntax lang=”bash”]
cp php.ini-dist /usr/local/lib/php.ini

If you installed the APC extension, You should add “extension=apc.so” to the bottom of the php.ini

Fix some brain dead exploit in PHP, edit php.ini and change cgi.fix_pathinfo=0
See http://wiki.nginx.org/Pitfalls#FastCGI_Path_in_Script_Name for more information.

I haven’t found a compatible  chkconfig style startup script for PHP-FPM yet

[codesyntax lang=”bash”]
echo /etc/init.d/php-fpm start >> /etc/rc.local

Create an unprivileged user for PHP-FPM to run and store data as

[codesyntax lang=”xml”]
groupadd www-data
useradd -g www-data -d /dev/null www-data

That’s it for compiling PHP. The only thing we have left to do is change some settings in the php-fpm conf. Open up /usr/local/etc/php-fpm.conf. Do some searching and change the users who own the processes to www-data, it should look something like;

[codesyntax lang=”xml”]
<value name=”owner”>www-data</value>
<value name=”group”>www-data</value>
<value name=”user”>www-data</value>
<value name=”group”>www-data</value>

I also like to change PHP-FPM to run as a socket, so we don’t have any TCP/IP overhead for extra, extra speed.

[codesyntax lang=”xml”]

<value name=”listen_address”>/var/run/php-fpm.sock</value>

Installing nginx

We’re compiling the Perl module into nginx for some funky goodness I will cover soon.

[codesyntax lang=”bash”]
yum install pcre-devel pcre

Now, configure nginx

[codesyntax lang=”bash”]

tar zpfvx nginx-0.9.5.tar.gz

cd nginx-0.9.5
./configure –without-mail_pop3_module –without-mail_imap_module –without-mail_smtp_module –with-http_ssl_module –with-http_stub_status_module  –with-http_gzip_static_module –with-http_perl_module
make
make install

I stole some config settings for nginx’s fastcgi_params file from http://interfacelab.com/nginx-php-fpm-apc-awesome/

[codesyntax lang=”bash”]
nano /usr/local/nginx/conf/fastcgi_params

And insert the following at the top

[codesyntax lang=”bash”]
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

We need to make nginx start on boot, I also stole this init script from Linode.

[codesyntax lang=”bash”]
wget https://library.linode.com/web-servers/nginx/installation/reference/init-rpm.sh
mv init-rpm.sh /etc/rc.d/init.d/nginx
chmod +x /etc/rc.d/init.d/nginx
chkconfig –add nginx
chkconfig –level 2345 nginx on

Although it needs some modification to work with our default settings.

[codesyntax lang=”bash”]
nano /etc/init.d/nginx

Change the following lines
[codesyntax lang=”bash”]
nginx=”/usr/local/nginx/sbin/nginx”
NGINX_CONF_FILE=”/usr/local/nginx/conf/nginx.conf”

Now just start them both!

[codesyntax lang=”bash”]
/etc/init.d/nginx start
/etc/init.d/php-fpm start

Simple as!

 

Author: Kieran Barnes

Kieran is a PHP developer with 15 years commercial experience. Specialist in WordPress, CakePHP, CubeCart and all things PHP.

8 thoughts on “Installing nginx & PHP-FPM securely on CentOS”

  1. THANKS A LOT. Good guide.

    I run make test just to check out everything and this I have found: (Should I care)

    TEST RESULT SUMMARY
    ———————————————————————
    Exts skipped : 47
    Exts tested : 32
    ———————————————————————

    Number of tests : 8863 6865
    Tests skipped : 1998 ( 22.5%) ——–
    Tests warned : 0 ( 0.0%) ( 0.0%)
    Tests failed : 16 ( 0.2%) ( 0.2%)
    Expected fail : 5 ( 0.1%) ( 0.1%)
    Tests passed : 6844 ( 77.2%) ( 99.7%)
    ———————————————————————
    Time taken : 443 seconds
    =====================================================================

    =====================================================================
    FAILED TEST SUMMARY
    output buffering – fatalism [tests/output/ob_011.phpt]
    ob_start(): Ensure unerasable buffer cannot be flushed by ob_flush() [tests/output/ob_start_basic_unerasable_005.phpt]
    Bug #42718 (unsafe_raw filter not applied when configured as default filter) [ext/filter/tests/bug42718.phpt]
    SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store. [ext/spl/tests/arrayObject_exchangeArray_basic3.phpt]
    Bug #39863 (file_exists() silently truncates after a null byte) [ext/standard/tests/file/bug39863.phpt]
    =====================================================================

    You may have found a problem in PHP.
    We would like to send this report automatically to the
    PHP QA team, to give us a better understanding of how
    the test cases are doing. If you don’t want to send it
    immediately, you can choose “s” to save the report to
    a file that you can send us later.
    Do you want to send this report now? [Yns]:

  2. Two more things. Remeber to point out to uncomment /usr/local/etc/php-fpm.conf the unix user lines.

    And maybe you miss to configure /usr/local/nginx/conf/nginx.conf:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
    fastcgi_pass /var/run/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }

    Also, can you comment on this lines of code?

    server {
    server_name _;
    root /var/www/site;
    location / {
    try_files $uri $uri/ @proxy;
    }
    location @proxy {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/tmp/phpcgi.socket;
    }

    The nginx wiki recommends to not proxy everything. How can this be applicable to this installation guide?

    Thanks

  3. Yep, worked like a charm. Only thing that was after testing smtp over ssl, it wouldn’t work since is not configure it to install php with it. Fix it recompiling.

    I must say I am very gratefull. Straigth to the point, great how to.

    One thought I have. If you let me express myself on your blog…

    I am 27 years old. I have been using Windows since ver 3, now with Windows 7. I loved to run programs from dos, configure, fix and look “cool” to my friends. Downloaded Unreal alpha demo over a 56 kbps in 2 days. My mom almost kill me.

    Now, this is my first run on Linux. Rented a Xen VPS, installed Centos (net install), installed everything from ssh. Last week I find webmin. Uninstalled later on since is more easy to use ssh.

    I know why Linux distribution didn’t work out yet. Assumming they are competing with Windows Server.

    We have Redhat (good support), CentOS (the same as Redhat without support and several repos and beta testing from the community) And the others… The BIG problem is REPOS, application configuration paths, application installation paths, weird application names. I know it is cool to just write “ls” and see the files, or “more” and see whats inside, but you should learn them. It would have been more ease too use Application variables. Yum remove app works, but yum uninstall app doesn’t. Same goes to apt-get. I can continue the list of “wrong things I see” but the point is Linux kernel is the envy of Microsoft. You guys have already a wonderfull, fully working and fully supported kernel. The only thing we need is a MAJOR rework on installation tools, configuration tools and manage tools, and Linux will be the next big OS of the next years.

    BTW, Now I am testing nginx and PHP 5.3.6 and PHP-FPM. Doesn’t work yet. LOL.

  4. Sorry, a whole phrase went deleted. When it says “It would have been more ease too use Application…” I meant “It would have been more ease too use “list” or “see”. Application …”

Leave a Reply

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