Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

community creator

How to set a web server using nginx & php-fpm for drupal stack

Hasbi Hamza

When you use PHP as a backend technology, you will always hear people talking about lamp stack (Linux - Apache - MySQL - PHP) for the web environment.

There are a lot of tools that can give you a bootstraped version of that stack depending on your OS:

These tools generally come preconfigured so that you can start developing on the fly. However, they are not meant to be present in your production servers. This means that you need to have at least some basic knowledge on how to set up your own stack or at least some basic configuration tricks.

When you want to host a PHP web app, the server you’ll be using will probably be a machine (or virtual for cloud-based services) with either Apache or Nginx as a web server.

In this series of shots, I will be covering a basic setup for a drupal 8 stack using Nginx - php-fpm - mariadb for Docker.

First of all, we’ll need to configure Nginx to let it know that we are using it as a web server and not as a proxy server. We will use the *.conf files to do this:

user www-data;
pid /run/;
worker_processes auto;

events {
        worker_connections 768;
        # multi_accept on;

http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        types_hash_max_size 2048;
        server_tokens off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_connect_timeout 1200s;
    proxy_send_timeout 1200s;
    proxy_read_timeout 1200s;
    proxy_busy_buffers_size 256k;
    gzip on;
    gzip_disable "msie6";

    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    brotli on;
    brotli_static on;
    brotli_buffers 32 8k;
    brotli_comp_level 7;
    brotli_types *;

    include /etc/nginx/conf.d/*.conf;


The HTTP directive is the most important aspect of this config as you can play with the value for buffer size, etc.

Note: In this case my webserver is configured to serve gzip and brotli compressed assets.

Furthermore, we need to add the site’s configwhere you put the domain name and other site-specific conf like browser cache, files access, redirections, etc.. This file will have the project’s specific configuration; however, some directives will never change:

upstream fastcgi_backend {
server php:9000;
keepalive 8;
server {
listen 80;
server_name *.dev;
root /var/www/html/;

location = /favicon.ico {
    log_not_found off;
    access_log off;

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;

# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
    deny all;

location ~ \..*/.*\.php$ {
    return 403;

location ~ ^/sites/.*/private/ {
    return 403;

location / {
    # try_files $uri @rewrite; # For Drupal <= 6
    gzip_static on;
    proxy_cache cache;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 3;
    proxy_cache_valid 200 1s;
    proxy_cache_use_stale updating error timeout;
    proxy_cache_background_update on;
    proxy_cache_lock on;
    try_files $uri /index.php?$query_string; # For Drupal >= 7

We can easily spot the main difference between nginx and apache as webservers:

Apache can execute your PHP scripts by activating modphpan apache extension. However, in Nginx’s case, you are forced to use php-fpm (fast cgi) to run your PHP scripts and pass them to the server, which only renders the execution results to the browser.

So, by following this directive:

location ~ '\.php$|^/update.php' {
    fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
    # Security note: If you're running a version of PHP older than the
    # latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
    # See for details.
    include fastcgi_params;
    # Block httpoxy attacks. See
    fastcgi_param HTTP_PROXY "";
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_intercept_errors on;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 64k;
    fastcgi_send_timeout 1200s;
    fastcgi_read_timeout 1200s;
    # PHP 5 socket location.
    #fastcgi_pass unix:/var/run/php5-fpm.sock;
    # PHP 7 socket location.
    # fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;

    fastcgi_pass fastcgi_backend;
    fastcgi_keep_conn on;
    # fastcgi_pass fpm:9000;

We can cover the Nginx configuration with php-fpm (which we have done, yay!).

Next, we will be setting up docker containers to run our stack (Nginx - php-fpm - MariaDB):

  • Click here for part 2


community creator

View all Courses

Keep Exploring