Nginx Setup for PHP with pretty Web API URL Support

Been trying to do this a few months ago for hosting a school project. It failed badly and I had to fallback to using Apache, which is easier to set up. Not that I have anything against Apache(used it for my Orbital project a few years back), just a change in preferences. This time, similar situation but maybe due to better understanding of the web server configurations(only slightly), I finally got it working after spending a few hours over a span of a few days.

There are MANY guides out there online on this topic already. I scoured through and tried a number of them, but all I got were 403, 500 and 502. Towards the end, I realised that if you get error 500, you already got the PHP code executed. It means your PHP code ran into runtime errors, which you should look for it in you Nginx error log. I will go through briefly the steps and finally provide a skeleton of a virtual host configuration that worked for me.

A few notes before I start, the paths to the configuration files vary slightly between Linux distros(I am using Arch on Raspberry Pi) but I will try to describe as distro-independent as possible.

First off, update the system, package manager and whatever you need. Then, install nginx and the PHP FastCGI package. For Ubuntu, it is
php5-fpm and for Arch it is php-fpm. This step is the easiest of them all. Digital Ocean has guides for Ubuntu and CentOS for such tasks and Arch wiki is pretty good in explaining how to do stuffs, especially what packages to install. You should have no problem with this at all.

Once the installation is done, you might want to make some tweaks in configuration for Nginx and PHP FPM. By default, the user is nginx or http in the configuration files. You can either change the user option in both configuration files(not a good practice? I still do it anyway for convenience) or apply the correct permissions to every folder along the way from the root to the target directory. For example, if your site’s document root is /a/b/c/d, you might want to do chmod 711 for directories a to d. Then, make sure the files to be served or run has read permission for others like nginx or http. If you choose to go the path of changing user and group parameters. go to the line with user in nginx.conf
and change it to your own username. For PHP FPM configuration file, go to the section starting with [www], change the value of user
and listen.owner to your own username. Note that this part is aimed at solving error 403.

The next step is to configure where should FastCGI listen for requests to PHP files. There are 2 options: through 127.0.0.1:9000
or UNIX socket. If using the former, do make sure that port 9000 is accessible from outside. Open the PHP FPM configuration file, go to the section starting with [www] , you will see 2 lines defining the parameter listen. One of them will be commented out with a semi-colon. Make sure the one you want is uncommented and vice versa. If using Unix socket, remember the fullpath of the Unix socket. Save and close the file. Note that you need to open as root for this and the previous part.

The last part can be very frustrating, the server block configurations. Wrong configurations can get you 502 Bad Gateway. On some systems, there are folders sites-available and sites-enabled. Otherwise, it is good practice to create these as subdirectories to the nginx directory. sites-available is where you will write your virtual host configurations and sites-enabled contains symlinks to the files in sites-available. Thus, you can turn on/off web applications by creating/removing symlinks. Make sure the line include sites-enabled/*.conf; exists in nginx.conf. The following configurations works for me, read the comments.


server {
  listen 80;  # port number
  server_name www.example.com;  #Web URL
  root /a/b/c/d; # Full path to project directory

  # The pretty URLs, pretty much like Apache's mod_rewrite
  # Refer to Nginx's rewrite syntax
  # Eg. rewrite ^/api/abc /a.php last;
  rewrite ^/api/abc /a.php last;

  # location regex string, read up online
  # I only used simple string matching
  location / { # The home page
    index index.html; # The home page file
  }

  # FastCGI config for requests for PHP files
  location ~ \.php$ {
    # Unix socket. This is for Arch.
    # Replace with the full path from earlier on.
    fastcgi_pass unix:/run/php-fpm/php-fpm.sock;

    # Uncomment this if not using Unix socket
    # fastcgi_pass 127.0.0.1:9000;

    include fastcgi.conf; # Path to fastcgi config file relative to nginx.conf
  }
}

Create the symlink to this file in sites-enabled. Restart PHP-FPM and Nginx and it should work. Hope this post has been helpful in setting up your LEMP.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s