FREE Webinar: Should I use React or Vue?
Deploying Laravel to DigitalOcean

Deploying Laravel to DigitalOcean

Code

In this tutorial, I’ll be showing you how to deploy a Laravel application to DigitalOcean. For the purpose of this tutorial, I have created a demo Laravel application, which we’ll be deploying to DigitalOcean. The demo application can be found on GitHub.

Prerequisites

This tutorial assumes the following:

Create a Droplet

We’ll start by spinning up a new server, which is referred to as droplet by DigitalOcean. Login to your DigitalOcean account and create a new droplet.

Create droplet

We’ll be making use of DigitalOcean's 1-Click Apps to quickly spin up our server. So under Choose an image, click on the Marketplace tab and type LEMP then select it from the result as shown below:

LEMP

Next, we’ll choose the $5/month plan, which is suitable for our demo application.

Choose plan

For the datacenter region, we’ll go with the default. Next, we’ll add our SSH key. If you have already added SSH keys to DigitalOcean before, you can choose from those:

React LogoReact Logo
Learn by Building
Build 20 React apps. Go beyond 'hello world'

Select SSH key

If not, you’ll need to click on the New SSH Key button to add a new SSH key. You can get your SSH key by running the command below on your local computer:

cat ~/.ssh/id_rsa.pub

The command above will print your SSH key on the terminal, which you can then copy and paste in the SSH Key Content field and give your SSH key a name.

Add SSH key

Finally, choose a hostname (if you don’t want the randomly generated name) for the droplet and click the Create Droplet button. We should now have a server up and running on Ubuntu 18.04 with the following software installed and configured:

LEMP softwares

Take note of the IP address of the server as we’ll be using it to access the server in subsequent sections.

Configuring The Server

As a security measure, it is recommended to carry out tasks on a server as a non-root user with administrative privileges. So before we start configuring our server, let’s create a non-root user which we’ll use to administer our server for the rest of the tutorial. First, we need to login to the server as root. We can do that using the server’s IP address. Enter the command below on your local computer:

ssh root@IP_ADDRESS

Once we are logged in to the server, we can move on to create a new user:

adduser mezie

This will create a new user called mezie, you can name the user whatever you like. You will be asked a few questions, starting with the account password. Having created the new user, we need to give it administrative privileges. That is, the user will be able to perform administrative tasks by using sudo command:

usermod -aG sudo mezie

The command above adds the user mezie to sudo group. Now, the user can run commands with superuser privileges. Next, let’s set up SSH key for the newly created user. You need to copy your public key to your new server. Enter the command below on your local computer:

cat ~/.ssh/id_rsa.pub

Copy the SSH key printed to the terminal. For the new user to login to the server with an SSH key, we must add the public key to a special file in the user's home directory. Still logged in as root on the server, run the command below:

su - mezie

This will temporarily switch to the new user. Now, you’ll be in your new user's home directory. Next, we need to create a new directory called .ssh and restrict its permission:

mkdir ~/.ssh
chmod 700 ~/.ssh

Within the .ssh directory, create a new file called authorized_keys:

touch ~/.ssh/authorized_keys

Open the file:

vim ~/.ssh/authorized_keys

and paste your public key (copied above) into the file. To save the file, hit esc to stop editing, then :wq and press ENTER. Next, restrict the permissions of the authorized_keys file with this command:

chmod 600 ~/.ssh/authorized_keys

Type the command below to return to the root user:

exit

Now, your public key is installed, and you can use SSH keys to log in as the new user. To make sure you can log in as the new user with SSH. Enter the command below in a new terminal on your local computer:

ssh mezie@IP_ADDRESS

If all went well, you’ll be logged in to the server as the new user with SSH. The rest of the tutorial assumes you are logged in to the server with the newly created user (mezie in my case). Because we chose 1-Click App while creating our droplet, ufw firewall is enabled, which keeps our server secured. Now, we need to open the firewall for only HTTP since we are not concerned with SSL in this tutorial:

sudo ufw allow 'Nginx HTTP'

Installing and Configuring MySQL

The demo application we’re deploying in this tutorial makes use of MySQL, so we need to install and configure MySQL on our server:

sudo apt install mysql-server

Next, let’s configure MySQL:

sudo mysql_secure_installation

Enter a root password when prompted, then answer the necessary options when prompted. With the MySQL configured, we need to create a database and a user. First, log in to the MySQL server:

mysql -u root -p

Provide the root password you enter above while installing MySQL. Once you are logged in, create a new user:

CREATE USER 'YOUR_USERNAME'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD';

Replace YOUR_USERNAME and YOUR_PASSWORD with your user and password respectively. Then execute the following command:

ALTER USER 'YOUR_USERNAME'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YOUR_PASSWORD';

This will allow us to use a password when connecting to MySQL as the created user. Remember to change YOUR_USERNAME and YOUR_PASSWORD to your database user and password respectively. Next, create a new database:

CREATE DATABASE laravel-deploy-demo;

Then we need to grant the new user privileges to the tables on the new database:

GRANT ALL ON laravel-deploy-demo.* TO 'YOUR_USERNAME'@'localhost';

For the changes to take effect, run:

FLUSH PRIVILEGES;

Finally, exit the MySQL server:

exit;

Installing Laravel Required PHP Extensions

Laravel requires some PHP extensions to be installed on our server. As it stands our server already have most of them installed, we just need to install the remaining ones ourselves:

sudo apt update && sudo apt install php-bcmath php-mbstring php-xml

Installing Composer

We need to Composer to install PHP packages, so let's make sure it's installed on our server. First, the let's install unzip, which is required by Composer for extracting packages:

sudo apt update && sudo apt install unzip

Now, we can install Composer:

curl -sS https://getcomposer.org/installer |php

Next, let'ts make sure Composer is installed system-wide command by move the Composer file to /usr/local/bin directory:

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

Now, we can access Composer from any using composer.

Pulling In Our Application

For the tutorial, I have created a demo Laravel application that we'll be deploying. We’ll be pulling in our application to our server using Git. We are going to clone the app unto the server inside /var/www directory:

cd /var/www
git clone https://github.com/ammezie/laravel-deploy-demo.git

Once cloned, run the following command to install the necessary packages:

cd laravel-deploy-demo
composer install

Laravel reads most of its configuration settings from environment variables, which are store inside a .env file located in the root of every Laravel application. This makes it easier to make use of different configuration settings depending on the environment (development, staging, production, etc.) the application is running. By default, Laravel ships a .env.example file, which can serve as a template for creating our application actual .env file. Let’s create the .env file:

cp .env.example .env

Next, we need to generate an APP_KEY:

php artisan key:generate

Open .env:

vim .env

and paste the following into it:

// .env

APP_NAME=laravel-deploy-demo
APP_ENV=production
APP_DEBUG=false
APP_URL=http://DOMAIN_NAME_OR_IP_ADDRESS

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-deploy-demo
DB_USERNAME=YOUR_DATABASE_USERNAME
DB_PASSWORD=YOUR_DATABASE_PASSWORD

Since we on production, we set APP_DEBUG to false. Also, we set APP_URL to our domain name or server IP address (if no domain name has been set up). Remember to update YOUR_DATABASE_USERNAME and YOUR_DATABASE_PASSWORD with your database details from the previous section. Now, we can run the migration:

php artisan migration:run --force

Because we are on production, we have to use the --force flag, otherwise, the migration will not run.

Setting Up Nginx

Next, let's configure Nginx to serve our application. For that, we'll create a new virtual host configuration file inside /etc/nginx/sites-available:

sudo vim /etc/nginx/sites-available/laravel-deploy-demo

and pasting in the following code:

// /etc/nginx/sites-available/laravel-deploy-demo

server {
    listen 80;
    server_name DOMAIN_NAME_OR_IP_ADDRESS;
    root /var/www/laravel-deploy-demo/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ .php$ {
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /.(?!well-known).* {
        deny all;
    }
}

We set the server_name to that of our server IP address or domain name (if it’s set up). Also, we set the root to point the public directory of our application, since it contains the index.php file, which serves as the entry file for a Laravel application. Next, we need to activate the newly created virtual host configuration file by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/laravel-deploy-demo /etc/nginx/sites-enabled/

To make sure there are no errors in the configuration, run the command below:

sudo nginx -t

Then we can restart Nginx for our changes to take effect:

sudo service nginx restart

Next, we need to give the web server write permissions to the storage and bootstrap/cache directories respectively:

sudo chown -R www-data.www-data /var/www/laravel-deploy-demo/storage
sudo chown -R www-data.www-data /var/www/laravel-deploy-demo/bootstrap/cache

Now, we should be able to access our application with our server’s IP_ADDRESS. If a domain name has been set up for our server, then we should be able to access our application using the domain name as well.

You should get something similar to the image below:

Demo

Conclusion

In this tutorial, we have seen how to deploy a Laravel application to DigitalOcean. Also, we saw how easy it is to spin up a new server with DigitalOcean’s 1-Click App.

Now, that we have successfully deployed our application, we can check out the optimization section of the Laravel docs on some optimization techniques we can take to improve our application's performance on production.

Like this article? Follow @ammezie on Twitter