[Series] Drupal Env using docker & nginx!
Tags: php, docker, nginx, drupal
Published: 2020-11-15 20:43:43

---
title: [Series] Drupal Env using docker & nginx!
published: true
description: Setting up a drupal env using docker.
tags: php,docker,nginx,drupal
---

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sm9qejlpv8py4a9asn9g.png)

When you are using php as a backend technology you will always hear people talking about lamp stack (linux - apache - mysql - php) for the web envirnoment.

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

 - [XAMPP](https://www.apachefriends.org/fr/index.html)
 - [WAMP](https://www.wampserver.com/)
 - [MAMP](https://www.mamp.info/en/)
 - [Acquia](https://dev.acquia.com/downloads)

 Those tools comes generally preconfigured so that you can start developing on the fly.
Those kind of tools are not meant to be present in your production servers which means that you need to have at least some basic knowledge on how to setup your own stack or at least some
basic configuration tricks.

When you wanna host a php web app , the server you'll be using is generally a machine (virtual for cloud based services) with either Apache or nginx as a web server.

In this series of articles 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 some configuration to give to nginx to let him know that we are using it as web server not proxy server , we use generally *.conf files to do that :

    user www-data;
	pid /run/nginx.pid;
	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 in this config you can always play with the value for buffer size etc ...Note that for this case my webserver is configured to serve gzip and brotli compressed assets you can learn about web server compression here : *[Gzip and Brotli compression](https://www.machmetrics.com/speed-blog/gzip-vs-brotli-best-browser-compression/)*.

Furthermore we need to add the site's conf ... It's generally where you put domain name and other site's specific conf like browser cache, files access, redirections...etc.
This file will have the project's specific configuration but note that some directives never change :

    upstream fastcgi_backend {
    server php:9000;
    keepalive 8;
	}
	server {
    listen 80;
    server_name domain.dev *.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 :

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t9vvklawykxnzt1q69mo.png)
**Apache can execute your php scripts by activating modphp which is an apache extension but in nginx's case you are forced to use php-fpm (fast cgi) to run your php scripts and
pass it to the server which will only render the execution results to the browser.**
How would he do that ? 
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 http://serverfault.com/q/627903/94922 for details.
        include fastcgi_params;
        # Block httpoxy attacks. See https://httpoxy.org/.
        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;
    }

Now we've covered the nginx configuration with php-fpm , next we will be setting up docker containers to run our stack (nginx - php-fpm - mariadb).


EDIT : [Part 2](https://dev.to/hamzahasbi/series-drupal-env-using-docker-nginx-2-24i5).