LowEndBox

Hosting Websites on Bare Minimum VPS/Dedicated Servers

How to Setup a Ngnix PHP-FPM MariaDB Stack Ubuntu

Tags: Date/Time: November 23, 2013 @ 2:36 pm, by Maarten Kossen

lowendtutorial

A couple of years back, getting a web server up and running involved setting up Apache, mod_php and MySQL. Everything was owned by “a user” and if a script needed file access, you would just chmod 777 all the files that needed to be accessed. Over the past couple of years, that landscape has shifted. Nowadays, mod_php is the slowest option you could probably go with and MySQL isn’t all hipster anymore since Oracle bought Sun. Apache is still at large, but requires more resources to accomplish what NGINX does with less.

So, let’s go set up a web server that runs NGINX, PHP-FPM and MariaDB! MariaDB is a MySQL fork created by the original author of MySQL. It’s slowly replacing MySQL as the database server on Linux distributions and I have to say, I’m a big fan as well. PHP-FPM is a process manager for PHP that makes PHP run independently from the web server, which has multiple advantages over including PHP in the web server process (which is wrong to being with).

I’ve written this guide for Ubuntu. The process should be the same on Debian or other Debian-based distributions. A CentOS version is to follow later.

NGINX and PHP-FPM

First, let’s clean out any packages that may make you go “why doesn’t it work?”:

sudo apt-get purge apache2* libapache2*

That’s Apache out the door, including any libraries. The above may or may not be necessary, depending on what kind of VPS you have and what kind of template. It’s safe to run it anyway.

Now, let’s install NGINX and PHP-FPM:

sudo apt-get install nginx php5-fpm

When this is done and you visit your server’s hostname or IP address, you should see the NGINX landing page. This means installation has succeeded.

On to the configuration. Open up /etc/nginx/sites-available/default. Look for a code block that looks like this:

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
#       fastcgi_split_path_info ^(.+\.php)(/.+)$;
#       # NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini
#
#       # With php5-cgi alone:
#       fastcgi_pass 127.0.0.1:9000;
#       # With php5-fpm:
#       fastcgi_pass unix:/var/run/php5-fpm.sock;
#       fastcgi_index index.php;
#       include fastcgi_params;
#}

This snippet is from NGINX’s default virtual host configuration file and enables us to run PHP-FPM with NGINX. We’re going to change it to this:

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini

#       # With php5-cgi alone:
#       fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}

As you see, we’ve commented out several lines. I’m going to explain them line by line.

location ~ \.php$ {

This matches any location ending in *.php, which make sure that such requests get into the following block of code.

fastcgi_split_path_info ^(.+\.php)(/.+)$;

This matches the script’s file name and any variables that may have been added after that. It splits it up into two variables for later use by NGINX.

fastcgi_pass unix:/var/run/php5-fpm.sock;

This line passes on the request to the PHP-FPM socket, which we’ll configure in a bit. It basically sends the request there for it to be handled.

fastcgi_index index.php;

This is the name of the file NGINX should fall back to if no filename is given.

include fastcgi_params;

This includes any parameters made by the fastcgi module (like the ones we split before) and makes them available to NGINX.

That’s it NGINX-wise, let’s configure PHP-FPM. Open up /etc/php5/fpm/pool.d/www.conf. Look for the following line:

listen = 127.0.0.1:9000

And change it to:

listen = /var/run/php5-fpm.sock

This tells PHP-FPM to open a UNIX socket rather than listening on a port. This should speed things up as well.

Now, restart both PHP-FPM and NGINX:

sudo service php5-fpm restart

sudo service nginx restart

And you’re good! NGINX now works with PHP files and passes those on to PHP-FPM. If you want to test this, create a file in /usr/share/nginx/www and put this in it:

<?php

phpinfo();

If you surf to that file, it should display information about your PHP environment. Be sure to remove the file afterwards, as you probably don’t want all those details lying around in the open.

MariaDB

The final step for this tutorial is installing MariaDB. This is usually trivially easy on Ubuntu, however, at the time of writing there is a version number conflict in Ubuntu 12.04 LTS. This could have been fixed meanwhile, so I’m going to give you two commands so you have all the flexibility you need.

Anyway, let’s first install a package required for this installation to succeed:

sudo apt-get install python-software-properties

Next, add MariaDB’s repository key:

sudo apt-key adv –recv-keys –keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

And finally the repository:

sudo add-apt-repository ‘deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu precise main’

This repository should suit you fine. If you want something closer to home, go here: https://downloads.mariadb.org/mariadb/repositories/

Now, update APT’s caches:

sudo apt-get update

And install MariaDB and php5-mysql, so we can use MariaDB with PHP later:

sudo apt-get install mariadb-server php5-mysql

If the above results in a situation of conflict, here is how to solve it:

sudo apt-get install mariadb-server libmysqlclient18=5.5.33a+maria-1~precise mysql-common=5.5.33a+maria-1~precise php5-mysql

The conflicting packages are usually libmysqlclient18 and mysql-common, which both MariaDB and MySQL provide. In order to install MariaDB, you need the MariaDB version of these packages. With the above command, I’ve told APT to use the versions I gave for those packages. To see which versions a package has, run:

apt-cache policy packagename

It should show you a list of versions with APT’s preferred one top. For MariaDB, you need the latest version from the MariaDB repository.

For now, let’s just assume you’re not running into a conflict or you’ve solved it. During the installation, you are being asked to fill out a root password for MariaDB. Like always, pick a strong one here. Once that’s done, there’s a final step:

sudo service php5-fpm restart

Restarting PHP-FPM so the MySQL plugin gets loaded.

That’s it, you’re good to go!

What’s Next

You’re ready to install a script or an application now, but there’s a couple of things you should know. First, we’ve only configured the default virtual host. This is not bad per se, but less suitable for a multi-user environment. Also, all files go into /usr/share/nginx/www and should be owned by www-data. This ensures everything keeps running smoothly. Finally, you need to set up a database by hand in case you need one. You could use a tool like PhpMyAdmin, but be sure to properly secure it.

As this guide was an introduction to installing a NGINX, PHP-FPM and MariaDB stack, there’s a lot more to write about it. For example, the multi-user or multi-site environment I mentioned before. But also running this efficiently on a LowEndBox. Possibly even making the installation easier and configuring SSL. That’s for the future, though ;-)

Up next time: An introduction to NGINX, PHP-FPM and MariaDB on CentOS

36 Comments

  1. Lucas:

    MariaDB? Interesting ;)

    November 23, 2013 @ 4:46 pm | Reply
    • Lucas:

      Just wonder, who give that names? :)

      November 24, 2013 @ 2:08 am | Reply
      • Michael “Monty” Widenius – He had forked his MySQL project and started MariDB on top of that. The name was given by him after his youngest daughter, Maria :)

        November 24, 2013 @ 2:57 pm | Reply
      • jvnadr:

        MySQL is same story, also. “My” is not from mine, but this is Widenius eldest daughter’s name!

        November 24, 2013 @ 8:17 pm | Reply
  2. MrOwen:

    It’s worth mentioning for nginx and php, users should use the Dotdeb repositories. These are often updated with the most recent nginx, php, and and MySQL (if you so choose to use it) packages (all usually updated only a day or two after the announcement of a new version) along with a few other things.

    November 23, 2013 @ 5:54 pm | Reply
  3. any recommendation on front end database manager, besides phpmyadmin or sqlbuddy?

    November 23, 2013 @ 7:26 pm | Reply
  4. exussum:

    Is this relevant ? https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/
    I always set the nginx server up to defend against that. But not sure if its still an issue

    November 23, 2013 @ 8:35 pm | Reply
    • He mentions the “cgi.fix_pathinfo = 0;” and the virtual server example is like WordPress’ mentioned as safe. Nevertheless it is a very nice tutorial and as long as you run nginx on the same server with your php workers you need the “try_files $uri =404;” line as well.

      Again it is a general purpose tutorial and maybe one should research alone about his or her application optimal/secure nginx virtual server configuration.

      Cheers!
      Panagiotis.

      November 27, 2013 @ 3:40 am | Reply
    • You’re the one with the brains here. I’m wanctihg for your posts.

      April 24, 2017 @ 10:57 am | Reply
    • You’re on top of the game. Thanks for sharing.

      July 5, 2017 @ 11:33 am | Reply
  5. Why not using php5-mysqlnd rather than using php5-mysql? :D

    November 23, 2013 @ 10:57 pm | Reply
    • Maarten Kossen:

      I believe that’s just for OS X, not sure though.

      November 24, 2013 @ 1:37 am | Reply
      • I’m using it on both Debian and CentOS and it’s working great. :D

        November 24, 2013 @ 3:21 am | Reply
        • Sonic:

          Why you use php5-mysqlnd? Less memory?

          November 24, 2013 @ 6:07 am | Reply
          • Because when i’m using php-mysql or php5-mysql with MariaDB there’s always dependency error. So i try to search proper solution and somehow i found php-mysqlnd. Well, it’s not throwing any error at all and everything working fine.

            November 24, 2013 @ 6:31 am
  6. Nice didn’t know of MariaDB till now thanks.

    November 24, 2013 @ 1:53 am | Reply
  7. ahmiq:

    thanks , waiting for centos tutorial

    November 24, 2013 @ 7:53 am | Reply
  8. dotnetnoob:

    I can’t find /etc/php5/fpm/conf.d/www.conf It is not there.

    November 24, 2013 @ 11:58 pm | Reply
    • For Debian the location is “/etc/php5/fpm/pool.d/www.conf”.

      November 25, 2013 @ 1:52 am | Reply
      • Maarten Kossen:

        Yeah, it should have been that. The one path that wasn’t in my notes was wrong ;-)

        November 26, 2013 @ 5:43 am | Reply
  9. Thanks! Cant wait for the centos version.

    November 26, 2013 @ 8:19 pm | Reply
  10. renw0rp:

    could you possibly write also about nginx + Ruby on Rails? Thanks in advance :)

    November 29, 2013 @ 11:37 am | Reply
  11. Sven:

    Why do you recommend that the files belong to www-data? They only should be readable by www-data usually, not writable. Therefore they shouldn’t belong to the same user that the HTTP server is running under.

    November 29, 2013 @ 4:50 pm | Reply
    • texteditor:

      convention, mostly, I’d assume

      November 29, 2013 @ 5:42 pm | Reply
    • WordPress needs to be able to read and write to files. On initial install, it need access to wpconfig, then for uploads and also depending on the plugin ur using.. But, most people fine tune the file ownership as time goes on. Security is an moving mark .

      December 22, 2013 @ 10:57 am | Reply
  12. Great tutorial – thanks.

    January 10, 2014 @ 3:31 pm | Reply

Leave a Reply

Some notes on commenting on LowEndBox:

  • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
  • Akismet is used for spam detection. Quoting webhostingtalk.com URL seems to get binned consistently here, but I do peek into the spam box frequently to publish those comments.
  • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

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