Grayscale profile picture

Patrique Ouimet


Setting Up Ubuntu 16.04 for Laravel Development (LEMP)

Aug 28, 2017

LEMP Stack

First we'll need to install the backend essentials: Nginx, MySQL, PHP (with FPM).


sudo apt-get update
sudo apt-get install nginx

You may verify the installation

sudo systemctl status nginx

Output should be similar too

nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2017-08-17 21:14:01 UTC; 2min 9s ago


sudo apt-get update
sudo apt-get install mysql-server

You'll be prompted to enter a password for the root user, enter something secure and memorable.

You may verify the installation

mysql --version


mysql  Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using  EditLine wrapper

PHP (FPM) with extensions

sudo apt-get update
sudo apt-get install php-fpm php7.0-zip php-curl php-cli php-mysql php-common php-mbstring php-xml

You may verify the installation

php -v


PHP 7.0.18-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.18-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies

Tweaking PHP-FPM

sudo nano /etc/php/7.0/fpm/php.ini

TIP: Within nano press Ctrl+W then type in "fix_pathinfo=1" then press Enter, should bring you right to the line to change.

Once the editor (nano) is open, find and uncomment the line with cgi.fix_pathinfo and set the value to


This is to prevent fpm from executing unwanted scripts.

Be sure to restart the service after editing the file

sudo systemctl restart php7.0-fpm

Setting up Git

sudo apt-get update
sudo apt-get install git

You may verify the installation

git --version


git version 2.7.4

Setting up Composer

This is easiest way to verify the installer and run the setup.

cd ~
nano bash-composer

Once nano opens copy and paste this into the file (Ctrl+Shift+V within the editor). Script taken from Composer website


php -r "copy('', 'composer-setup.php');"
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")

    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1

php composer-setup.php --quiet
rm composer-setup.php
exit $RESULT

Now save the file and exit (Ctrl+X then type 'y' then Enter/Return).

Now run the following command

bash bash-composer

If the signature fails you'll see ERROR: Invalid installer signature, otherwise there will be no output.

Now we need to move composer.phar so we can use it as a command

sudo mv composer.phar /usr/local/bin/composer

Now try running


The output should look like

  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
Composer version 1.4.1 2017-03-10 09:29:45

  command [options] [arguments]

  -h, --help                     Display this help message
  -q, --quiet                    Do not output any message
  -V, --version                  Display this application version
      --ansi                     Force ANSI output
      --no-ansi                  Disable ANSI output
  -n, --no-interaction           Do not ask any interactive question
      --profile                  Display timing and memory usage information
      --no-plugins               Whether to disable plugins.
  -d, --working-dir=WORKING-DIR  If specified, use the given directory as working directory.
  -v|vv|vvv, --verbose           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  about           Short information about Composer.
  archive         Create an archive of this composer package.
  browse          Opens the package's repository URL or homepage in your browser.
  clear-cache     Clears composer's internal package cache.
  clearcache      Clears composer's internal package cache.
  config          Set config options.
  create-project  Create new project from a package into given directory.
  depends         Shows which packages cause the given package to be installed.
  diagnose        Diagnoses the system to identify common errors.
  dump-autoload   Dumps the autoloader.
  dumpautoload    Dumps the autoloader.
  exec            Execute a vendored binary/script.
  global          Allows running commands in the global composer dir ($COMPOSER_HOME).
  help            Displays help for a command
  home            Opens the package's repository URL or homepage in your browser.
  info            Show information about packages.
  init            Creates a basic composer.json file in current directory.
  install         Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.
  licenses        Show information about licenses of dependencies.
  list            Lists commands
  outdated        Shows a list of installed packages that have updates available, including their latest version.
  prohibits       Shows which packages prevent the given package from being installed.
  remove          Removes a package from the require or require-dev.
  require         Adds required packages to your composer.json and installs them.
  run-script      Run the scripts defined in composer.json.
  search          Search for packages.
  self-update     Updates composer.phar to the latest version.
  selfupdate      Updates composer.phar to the latest version.
  show            Show information about packages.
  status          Show a list of locally modified packages.
  suggests        Show package suggestions.
  update          Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file.
  validate        Validates a composer.json and composer.lock.
  why             Shows which packages cause the given package to be installed.
  why-not         Shows which packages prevent the given package from being installed.

Now let's add the composer global vendor bin to our path

sudo nano ~/.profile

The path probably looks something like


Update it to include the ~/.composer/vendor/bin directory


And now source the ~/.profile file

source ~/.profile

NOTE: If you prefer you may do all the steps involving ~/.profile within your ~/.bashrc

Setting up Laravel Installer

composer global require "laravel/installer"

You may verify the installation

laravel --version


Laravel Installer 1.3.3

Setting up Laravel Valet (Linux)

We'll need to install a few dependencies Valet Linux has

sudo apt-get update
sudo apt-get install network-manager libnss3-tools jq xsel

Then install the package globally via composer

composer global require cpriego/valet-linux

Now we have to run the Valet installer (doesn't matter which directory you're in)

valet install

To verify the installation ping any domain ending with .dev, as an example


If properly installed you should see a response from

64 bytes from localhost ( icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from localhost ( icmp_seq=2 ttl=64 time=0.063 ms

Now we need to create a directory where all your projects will live and tell Valet of it's existence. I like creating ~/code directory

mkdir ~/code
cd code
valet park

Now create a test project

laravel new test

Let's tell Valet to server the new project

cd test
valet link

Visit the following address and be amazed!

You may see any linked projects and their domains

valet links


| Site | SSL | URL             | Path                   |
| test |     | | /home/ubuntu/code/test |


That's it! It seems like a lengthy process but from now on all you do is add projects (directories) to ~/code then link the project and you're up and running! A lot of people will prefer the Homestead route (virtual machine) but I find the workflow slow and I prefer to use the host machine resources rather than sharing with a virtual machine.

Hope you liked my article, please leave comments and share if you like!