Symfony 4 LEMP (Linux, nginx, PHP, MySQL) Setup


This tutorial covers installing the LEMP stack for a Symfony 4 website.

The LEMP stack is:

  • Linux (Ubuntu)
  • nginx (pronounced Engine-x)
  • MySQL
  • PHP

We're going with PHP 7.2, as it is the most current PHP version at the time of recording.

PHP 7.1.3 is the bare minimum PHP version required to run a Symfony 4 application.

This tutorial is almost identical to the LEMP tutorial for Symfony 3.

However, as mentioned, our PHP version will be different.

The nginx server configuration is slightly different, to reflect the Symfony 4 directory structure.

We will also need to do a little extra setup regarding environment variables. This will be done in the next video.

I'm going to provide abbreviated steps here, but if you'd like the full steps, please watch this video, and adapt the PHP and nginx sections accordingly.

Spinning Up A Server

To begin with we are going to create a new Digital Ocean Droplet using the $10 plan, installing a fresh copy of Ubuntu 16.04.3 x64 as our virtual server / droplet Operating System.

You can follow this process on a different VPS provider such as Linode, or Amazon AWS.

If you do not yet have a Digital Ocean account, please create one now. By using this link you will get $10 initial credit, which is going to be more than enough to complete all the examples in this course. Full disclosure: this is an affiliate link.

Be sure to upload your SSH key(s) as available. If you do not have an SSH key, then please follow this guide.

Creating your new Droplet should take about 30 seconds.

Once done, you should be able to SSH into the box by running:

ssh root@138.197.105.140

Change your IP address accordingly.

I'm going to assume you have created a local entry in /etc/hosts or similar, and have a added an entry such as:

# from your local machine
# in the /etc/hosts file
# (or windows equivalent)

138.197.105.140  crvfakeexample.com

Installing PHP 7.2 For Symfony 4

Symfony 4 expects at least Symfony 7.1.3.

In order to install PHP 7.1 or greater, a standard installation of Ubuntu needs a little help.

PHP 7.0 is the release of PHP available in the currently supplied Ubuntu package list. At the time of recording, in order to install PHP 7.1, or PHP 7.2, we can use a third party package list.

apt-get install python-software-properties -y
add-apt-repository ppa:ondrej/php
apt-get update

apt-get install php7.2 \
  php7.2-cli \
  php7.2-common \
  php7.2-mysql \
  php7.2-gd \
  php7.2-fpm \
  php7.2-intl \
  php7.2-xml \
  php7.2-mbstring \
  php7.2-zip

This installs PHP 7.2, the latest and greatest at the time of recording:

php -v
PHP 7.2.0-2+ubuntu16.04.1+deb.sury.org+2 (cli) (built: Dec  7 2017 20:14:31) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.2.0-2+ubuntu16.04.1+deb.sury.org+2, Copyright (c) 1999-2017, by Zend Technologies

nginx Server Setup

Switch back to your server's terminal session now.

apt-get update
apt-get install nginx -y
rm /etc/nginx/sites-enabled/default
cd /etc/nginx/conf.d
touch crvfakeexample.com.conf
vim crvfakeexample.com.conf

Ok, so we have achieved quite a lot there. There's nothing new, again, if unsure please watch the previous video where all of this and more was covered in greater depth.

The server config we need is as follows:

server {
    listen 80 default;
    server_name crvfakeexample.com www.crvfakeexample.com;
    root /var/www/crvfakeexample.com/public;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # optionally set the value of the environment variables used in the application
        # fastcgi_param APP_ENV prod;
        # fastcgi_param APP_SECRET <app-secret-id>;
        # fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";

        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/index.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    # return 404 for all other php files not matching the front controller
    # this prevents access to other php files you don't want to be accessible.
    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/crvfakeexample.com_error.log;
    access_log /var/log/nginx/crvfakeexample.com_access.log;
}

This is largely copied from the Symfony nginx example, with the paths changed to reflect the new directory structure.

We will need to tweak this file again during the setup of our environment variables.

After saving and exiting, be sure to enable the site and reload nginx:

service nginx configtest
service nginx reload

We shall also need to install MySQL.

apt-get install mysql-server

Follow the prompts.

You will be asked to provide a root password.

To make your life as easy as possible, use the password of pass.

It shouldn't need saying, but of course don't use this password in production. This is a demo / example.

This is our basic LEMP server setup for Symfony 4.

Code For This Video

Get the code for this video.

Episodes