20 March 2017

Setting up picoCMS with NGINX and php-fpm

Installing picoCMS under Apache is well documented but getting it completely running using NGINX isn't as much, so I though that a good first post for this Blog would be a bunch of configuration fragments which I use for running picoCMS under NGINX.

I will not cover the installation & basic configuration of php-fpm - that's something I will maybe cover in another post. For now I just expect that you already have a running NGINX & php-fpm stack on default settings. If you already have changed settings like sockets and so on for php-fpm you have to change those in the examples.

The first part is creating a new file in /etc/nginx/sites-available for the virtual host.

The usual start is creating a server directive where you define the DNS of your server as well as the document root:

server {
    server_name YOUR_DNS.TLD;
    listen 80;
    root /var/www/your_filesystem_path_to_picocms;
    index index.php;

With this block we have defined to listen on YOUR_DNS.TLD on port 80 for connections and if a client connects, nginx will try to serve files out of /var/www/your_filesystem_path_to_picocms.

We also define the file index.php as the default file to be started. For now NGINX is still unable to server PHP files though.

Let's teach NGINX how to handle PHP Files:

PHP Locationblock:

location ~ \.php$ {
              include fastcgi_params;
              fastcgi_pass unix:/var/run/php5-fpm.sock;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_index index.php;
              fastcgi_keep_conn on;
              add_header Strict-Transport-Security max-age=15768000;
              fastcgi_param PICO_URL_REWRITING 1;

The last step is enabling the rewriting (as NGINX doesn't use .htaccess) and while we are at it we also limit the access to Picos "system"-Files like the source-files and system-folders. The first part internally redirects all URLs to index.php?$THEPATHYOUENTERED$ARGUMENTS_YOU_ADDED, while the second part throws a 404 if a user tries to access the system files & folders.

location ~ ^/(.*) {
    index index.php;
    try_files $uri $uri/ /index.php?$1&$args;

location ~ /(\.htaccess|\.git|config|content|content-sample|lib|vendor|CHANGELOG\.md|composer\.(json|lock)) {
    return 404;

location / {
    try_files $uri $uri/ /index.php?$uri&$args;