How to deploy a Laravel 5.6 project on a fresh Ubuntu 16.04 VPS/Server (DigitalOcean or similar hosts)

I’ve been experimenting with Server setup and Deployment options for Laravel 5.6. If you’re willing to pay $12-19 per month, you can use ready-made solution by Forge or Moss (I liked moss better).

However, If you want total control over your site and/or not willing to spend that $12-19 per month, follow along. Actually you can setup a host suitable for Laravel just by copy-pasting some commands. After the environment is ready, you can just git-clone/pull your project and run some artisan command to deploy your app. There’s no script that you need to run, just a bunch of commands and a template server config file (for nginx). That template file can also be replicated for hosting multiple sites (again using terminal commands). Since there’s no large scripts, you can make your tweaks easily if you want.

What you need

  1. A VPS or Server with root access with Ubuntu 16.04 installed (I created mine on DigitalOcean)
  2. A domain/subdomain pointed to that server’s IP address (You can do that by setting ‘A Value’ in your DNS manager)

What We’re going to install

  1. nginx
  2. mariadb 10.2
  3. php 7.2
  4. and bunch of other packages


Show me the code!!!

Login as root user and copy paste the following lines (you can copy the whole block). If you don’t have root access but a ‘sudo’ user, you many need to add sudo before each command.

Add repository and Install the required packages

apt-get install software-properties-common
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
add-apt-repository -y 'deb [arch=amd64,i386,ppc64el] http://mirrors.coreix.net/mariadb/repo/10.2/ubuntu xenial main'
add-apt-repository -y 'ppa:ondrej/php'
add-apt-repository -y 'ppa:ondrej/nginx'
add-apt-repository -y ppa:certbot/certbot
apt-get update
apt-get -y install gcc curl gzip sqlite3 git tar software-properties-common nginx php7.2-fpm php7.2-xml php7.2-bz2 php7.2-zip php7.2-mysql php7.2-intl php7.2-gd php7.2-curl php7.2-soap php7.2-mbstring python-certbot-nginx composer mariadb-server
###

Enter mysql root password when asked

Configure PHP

We’ll now enter some command to replace some of the php.ini settings (upload_max_filesize, max_execution_time, max_input_time, post_max_size, memory_limit). You can paste the following block into a text editor to make your tweak if you want before pasting into the terminal.

sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 20M/g' /etc/php/7.2/fpm/php.ini
sed -i 's/max_execution_time = 30/max_execution_time = 300/g' /etc/php/7.2/fpm/php.ini
sed -i 's/max_input_time = 60/max_input_time = 300/g' /etc/php/7.2/fpm/php.ini
sed -i 's/post_max_size = 8M/post_max_size = 28M/g' /etc/php/7.2/fpm/php.ini
sed -i 's/memory_limit = 128M/memory_limit = 512M/g' /etc/php/7.2/fpm/php.ini
service php7.2-fpm restart
###

Configure a site for nginx

Clone this git repo (it has a template for an nginx site)

git clone https://github.com/AfzalH/lara-server.git && cd lara-server
###

 

Enter the following command and then enter the target domain/subdomain (it will be stored in a variable) – Repeat for creating more sites

echo 'Enter Site Domain [site.com]:' && read site_com
###

 

Move the template config and replace the domain name (you don’t need to edit the file)

cp nginx/srizon.com /etc/nginx/sites-available/$site_com
sed -i "s/srizon.com/${site_com}/g" /etc/nginx/sites-available/$site_com
mkdir /var/www/$site_com
mkdir /var/www/$site_com/public
touch /var/www/$site_com/public/index.php
ln -s /etc/nginx/sites-available/$site_com /etc/nginx/sites-enabled/$site_com
service nginx reload
###

 

Move to document root to clone your project

cd /var/www/$site_com

 

Create Database

mysql -u root -p

After entering the password it will go into mariadb console where you can paste the following lines (change dbname, username and password before pasting)

CREATE DATABASE dbname;
GRANT ALL ON dbname.* TO username@localhost IDENTIFIED BY 'password';
exit;

Assuming you cloned your laravel project, you can now do the following to set it up.
Copy the .env.example and edit the .env file to put production configurations

cp .env.example .env
nano .env
# after editing ctrl+o , enter, ctrl+x

Give ownership to nginx/php

chown -R www-data:www-data *

Install composer packages

composer install

 

Run necessary artisan commands

php artisan key:generate
php artisan migrate
# if your app uses storage
php artisan storage:link
# if you are using passport
php artisan passport:install
# if you need to seed your database (.env must not be in production)
php artisan db:seed

Your Laravel app should be up and running!

Bonus!!!

If your app has no subdomain or www subdomain (site.com or www.site.com), you can secure (https) your site with one more command (and following the prompt afterwards)

certbot --nginx

If you face any problem, open an issue on GitHub