lesson

Completely Deploy Your Laravel Application on Ubuntu / Linux Server

author
Mumuni Mohammed
Posted: 5 months ago Updated: 19 hours ago
image

Completely Deploy Your Laravel Application on DigitalOcean Cloud Platform

I always watch different tutorials to deploy my Laravel application. This is because I haven't found any tutorial that really covers everything I want without navigating to other sites. Today, I have put together most of what you need to do to fully deploy your laravel application on a Linux server. This tutorial is made from the different tutorials I have read. This covers from launching a server to adding a domain and configuring SSL/TLS. Feel free to reach out if you spot anything that might be an issue in this post. I have also left some errors I encountered while hosting. These might be of help in case you encounter any errors.

Things we would cover:

1. Create and Deploy Your Droplet (Linux Server)

Login to the digital ocean console.

Click create and choose droplets.

Create DropletNext is to choose an Image and Plan

Select Ubuntu 

Then choose a plan that best describes your app requirements. 

I selected Basic and went for Regular Intel with SSD. Then went ahead to select a $10 droplet per month. 

Select any for your specifications and the minimum I will recommend for a laravel application is Regular Intel $10 per month. 

Droplet Image and Plan

The next step is to select your region. 

Region

Next is to setup the authentication method. 

It is best to use ssh keys to login. Using password login is less secured. Use ssh keys. If you don't have any public key on digitalocean, then click New SSH Key. 

SSH KeysWhen you click new, it will definitely guide you to add a key based on whatever OS you are running locally. 

New SSH

Finalize and Create Droplet

Finalize your droplet by choosing a hostname, and adding tags. 

If you need to enable backups, you can select that option. 

Create Droplet

Final Droplet

2. Login and create a sudo user

Get the IP address from the console and login. 

$ ssh root@your-ip-address

IP AddressLogin

Run updates and upgrade the server packages. 

$ apt-get update && apt-get upgrade -y

Add user

$ adduser username

Adduser

Grant user sudo privileges

$  usermod -aG sudo username

 

sudo-add

You can then switch to your user with:

$ su - username

You can run sudo commands using 

$ sudo

 

3. Install MySQL and set it up securely

MySQL is an open-source database management system, commonly installed as part of the popular (Linux, Apache, MySQL, PHP/Python/Perl) stack. It uses a relational database and SQL (Structured Query Language) to manage its data.

It is best to provision a standalone database and get the endpoints to connect to. You can provision it from anywhere. Check on the digitalocean console, choose Create, and select databases to create your database cluster. 

In this tutorial, I will create the database on the same server that will host our application. 

The short version of the installation is simple: update your package index, install the mysql-server package, and then run the included security script.

$ sudo apt update

$ sudo apt install mysql-server

 

Configure it securely:

For fresh installations, you’ll want to run the included security script. This changes some of the less secure default options for things like remote root logins and sample users. On older versions of MySQL, you needed to initialize the data directory manually as well, but this is done automatically now.

Run the security script:

$ sudo mysql_secure_installation

This will take you through a series of prompts where you can make some changes to your MySQL installation’s security options. The first prompt will ask whether you’d like to set up the Validate Password Plugin, which can be used to test the strength of your MySQL password. Regardless of your choice, the next prompt will be to set a password for the MySQL root user. Enter and then confirm a secure password of your choice.

From there, you can press Y and then ENTER to accept the defaults for all the subsequent questions. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MySQL immediately respects the changes you have made.

MySQL setupSql setup

Setup Authentication for Database Users

In order to use a password to connect to MySQL as root, you will need to switch its authentication method from auth_socket to mysql_native_password. To do this, open up the MySQL prompt from your terminal:

$  sudo mysql

 

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
mysql> FLUSH PRIVILEGES;
mysql> exit

 

Try signing without password and you will be denied access. 

$  sudo mysql

 

To login use:

$ mysql -u root -p

Then enter the password

 

4. Install Nginx and PHP

Install the Nginx Web Server

$ sudo apt install nginx -y

If you have the ufw firewall enabled, as recommended in our initial server setup guide, you will need to allow connections to Nginx. Nginx registers a few different UFW application profiles upon installation. To check which UFW profiles are available, run:

$ sudo ufw app list
Output

Available applications:

    Nginx Full

    Nginx HTTP

    Nginx HTTPS

    OpenSSH

It is recommended that you enable the most restrictive profile that will still allow the traffic you need. Since you haven’t configured SSL for your server in this guide, you will only need to allow regular HTTP traffic on port 80.

Enable this by typing:

$ sudo ufw allow 'Nginx HTTP'

Verify by typing:

$ sudo ufw status

Output

Status: active

To Action From

-- ------ ----

OpenSSH ALLOW Anywhere

Nginx HTTP ALLOW Anywhere

OpenSSH (v6) ALLOW Anywhere (v6)

Nginx HTTP (v6) ALLOW Anywhere (v6)

 

In case you don't have OpenSSH in your ufw list, enable it. 

$ sudo ufw allow 'OpenSSH'

To enable ufw, type: 

$ sudo ufw enbale

Visit your website IP to verify that Nginx is running:

$ http://server_IP

Nginx

Yaay! It works!

Let's move on...

Installing PHP

You have Nginx installed to serve your content and MySQL installed to store and manage your data. Now you can install PHP to process code and generate dynamic content for the webserver.

You’ll need to install php-fpm, which stands for “PHP fastCGI process manager”, and tell Nginx to pass PHP requests to this software for processing. Additionally, you’ll need php-mysql, a PHP module that allows PHP to communicate with MySQL-based databases. Core PHP packages will automatically be installed as dependencies.

To install the php-fpm and php-mysql packages, run:

$ sudo apt install php-fpm php-mysql php-cli -y

Install the packages below to be used to clone or unzip your project. 

$ sudo apt install unzip git curl -y

Let's move on to install composer. 

 5. Install Composer to help in your laravel application

You first need to download it. 

$ cd ~

$ curl -sS https://getcomposer.org/installer -o composer-setup.php

Next, we’ll verify that the downloaded installer matches the SHA-384 hash for the latest installer found on the Composer Public Keys / Signatures page. To facilitate the verification step, you can use the following command to programmatically obtain the latest hash from the Composer page and store it in a shell variable:

$ HASH=`curl -sS https://composer.github.io/installer.sig`
$ echo $HASH

You should see the output.

Now execute the following PHP code, as provided in the Composer download page, to verify that the installation script is safe to run:

$ php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;

You will see the following output: 

Installer verified

If the output says Installer corrupt, you’ll need to download the installation script again and double-check that you’re using the correct hash. Then, repeat the verification process. When you have a verified installer, you can continue.

To install composer globally, use the following command which will download and install Composer as a system-wide command named composer, under /usr/local/bin:

$ sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

Next, test your composer by typing: 

$ composer

 

6. Setup MySQL laravel user with permissions only to the specified database

Before we do this, let's install a few dependencies for our application.

$ sudo apt-get install php-mbstring php-xml php-bcmath

Now login and create your database. 

$ mysql -u root -p

Enter your password

Create the database

mysql> create database dbname;

Change dbname to the name you want for your database. 

Create a laravel_user for the database. Remember not to use the root user credentials in your app. By the way, we disabled the root user remote login, so you will definitely get an error if you try to use the credentials. 

The goal is to create a user and grant access to only the database created. 

Create user:

mysql> CREATE USER 'laravel_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

Change the password to a stronger one. 

Let's grant the user database access. 

mysql> GRANT ALL ON dbname.* TO 'laravel_user'@'%';

Exiit the mysql prompt and try to log in as the new user and verify that the user has access to only the database given. 

$ mysql -u laravel_user -p

Enter the password

Look at the images below if you are lost. 

 

 7.  Deploy your laravel application

Get the https link of your GitHub project. 

Clone it on the server www directory. 

$ cd /var/www/
$ sudo git clone git_url

Give the project ownership to your user.

$ sudo chown -R $USER:$USER /var/www/project-folder

Copy the .env.example to .env

$ cd project-folder
$ cp .env.example .env

Let's run composer to install our application vendor files.

$ composer install

Open your .env and specify the database credentials

$ nano .env

The only places you will change are:

DB_DATABASE=dbname

DB_USERNAME=laravel_user

DB_PASSWORD=password

We are good to run migrations and seeder

Run migrations:

$ php artisan migrate

I have seeder files so I run the command below:

$ php artisan db:seed

If you are using the storage directory to store your files, run:

$ php artisan storage:link

Change the group and mode of the storage and bootstrap

$ sudo chgrp -R www-data storage bootstrap/cache

$ sudo chmod -R ug+rwx storage bootstrap/cache

Enable your website with Nginx

The application files are now in order, but we still need to configure Nginx to serve the content. To do this, we’ll create a new virtual host configuration file at /etc/nginx/sites-available:

$ sudo nano /etc/nginx/sites-available/your_domain

The following configuration file contains the recommended settings for Laravel applications on Nginx:

server {
    listen 80;
    server_name your_domain www.your_domain;
    root /var/www/your_project/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.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

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

 

 

Copy this content to your /etc/nginx/sites-available/your_domain file and, if necessary, adjust the highlighted values to align with your own configuration. Save and close the file when you’re done editing.

To activate the new virtual host configuration file, create a symbolic link to your_domain in sites-enabled:

$ sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Unlink the default settings

$ sudo unlink /etc/nginx/sites-enabled/default

To confirm that the configuration doesn’t contain any syntax errors, you can use:

$ sudo nginx -t

You will see the output with a successful message. Check the image below.

To apply the changes, reload Nginx with:

$ sudo systemctl reload nginx

At this point, you can visit your IP or website domain name to view the app. 

The domain will only work if you point your domain name servers to the digitalocean nameservers. 

 8. Connect your domain

Let's now add the domain since we already configured it with nginx.

Go back to the digitalocean console. Click on three dots for more options.

Enter for the first entry. 

@ will point to your top level domain. 

Enter a new record. Type www.

If you just pointed your domain to digitialocean, it will take some time for it to reflect. Just be patient on this part. Don't think you didn't follow the steps well. 

 

 9. Configure SSL/TLS with Let's Encrypt and enforce HTTPS

Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx.

We will use Certbot to obtain a free SSL certificate for Nginx on Ubuntu 20.04 and set up our certificate to renew automatically.

Installing Certbot

Install Certbot and it’s Nginx plugin with apt

$ sudo apt install certbot python3-certbot-nginx

Allowing HTTPS Through the Firewall

To additionally let in HTTPS traffic, allow the Nginx Full profile and delete the redundant Nginx HTTP profile allowance:

$ sudo ufw allow 'Nginx Full' 

$ sudo ufw delete allow 'Nginx HTTP'

Verify your rules

$ sudo ufw status

Obtaining an SSL Certificate

Certbot provides a variety of ways to obtain SSL certificates through plugins. The Nginx plugin will take care of reconfiguring Nginx and reloading the config whenever necessary. To use this plugin, type the following:

$ sudo certbot --nginx -d example.com -d www.example.com

If this is your first time running certbot, you will be prompted to enter an email address and agree to the terms of service. After doing so, certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that you control the domain you’re requesting a certificate for.

If that’s successful, certbot will ask how you’d like to configure your HTTPS settings.

 

Output

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

Select your choice then hit ENTER. The configuration will be updated, and Nginx will reload to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:

 

Output

IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

 

Verifying Certbot Auto-Renewal

Let’s Encrypt’s certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a systemd timer that will run twice a day and automatically renew any certificate that’s within thirty days of expiration.

You can query the status of the timer with systemctl:

$ sudo systemctl status certbot.timer
Output

● certbot.timer - Run certbot twice daily Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled) Active: active (waiting) since Mon 2020-05-04 20:04:36 UTC; 2 weeks 1 days ago Trigger: Thu 2020-05-21 05:22:32 UTC; 9h left Triggers: ● certbot.service

To test the renewal process, you can do a dry run with certbot:

$ sudo certbot renew --dry-run

If you see no errors, you’re all set. When necessary, Certbot will renew your certificates and reload Nginx to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.

 

 10. Common errors encountered

When deploying you might encounter some errors. I have compiled some errors with their solutions. 

i. Laravel storage issues

 

I actually addressed this issue already. But just run the following commands in your project.

$ sudo chgrp -R www-data storage bootstrap/cache

$ sudo chmod -R ug+rwx storage bootstrap/cache

 

I will be updating this tutorial regularly.  

 

 

 References

Great thanks to the wonderful people who put together these. Check any of the links below for your reference. 

https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-18-04

https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-install-and-use-composer-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-laravel-with-nginx-on-ubuntu-20-04

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

 

 

Navigate back to any.

 

Like Tutorial

Share Tutorial

0 Comments

Author
avatar
Mumuni Mohammed

I studied electrical and electronic engineering at Ashesi University but decided to self-study computer science and eventually found a career in it. My great passion is bringing healing to people who have been through a stressful experience with learning. I help students to find healthy perceptions of themselves and strengthen their relationships so that they can know themselves and face learning without any fear.

I am currently learning and doing more of DevOps and Ceph.

Follow
More From Kalkulus
https://ktechhub.fra1.digitaloceanspaces.com/tutorials/1628760126.pic25.png
Hosting Your Laravel App On Heroku
408 Views 4 months ago
https://ktechhub.s3.amazonaws.com/tutorials/241y4U4UpCsrEx4Tv4xm3KVfZ1FTGh29SMMCOlMo.png
Fixed - zsh: corrupt history file
521 Views 7 months ago
Popular Topics
Angular
Python

1 Tutorials

arrow_right
Angular
Python

1 Tutorials

Python is a computer programming language often used to build websites and software, automate tasks, and conduct data analysis.

Angular
Laravel

3 Tutorials

arrow_right
Angular
Laravel

3 Tutorials

Laravel is a free, open-source PHP web framework, intended for the development of web applications following the model–view–controller architectural pattern and based on Symfony.

Angular
Django

2 Tutorials

arrow_right
Angular
Django

2 Tutorials

Django is a Python-based free and open-source web framework that follows the model–template–views architectural pattern.

Angular
Flask

1 Tutorials

arrow_right
Angular
Flask

1 Tutorials

Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries.

Angular
PHP

3 Tutorials

arrow_right
Angular
PHP

3 Tutorials

PHP is a general-purpose scripting language geared towards web development.

Angular
AWS

1 Tutorials

arrow_right
Angular
AWS

1 Tutorials

Amazon Web Services is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered pay-as-you-go basis.

Angular
Microsoft Azure

1 Tutorials

arrow_right
Angular
Microsoft Azure

1 Tutorials

Microsoft Azure, commonly referred to as Azure, is a cloud computing service created by Microsoft for building, testing, deploying, and managing applications and services through Microsoft-managed data centers.

Angular
GCP

1 Tutorials

arrow_right
Angular
GCP

1 Tutorials

Google Cloud Platform, offered by Google, is a suite of cloud computing services that runs on the same infrastructure that Google uses internally for its end-user products, such as Google Search, Gmail, file storage, and YouTube.

Angular
Digitalocean

1 Tutorials

arrow_right
Angular
Digitalocean

1 Tutorials

DigitalOcean, Inc. is an American cloud infrastructure provider headquartered in New York City with data centers worldwide. DO provides developers cloud services that help to deploy and scale applications that run simultaneously on multiple computers.

Angular
General

2 Tutorials

arrow_right
Angular
General

2 Tutorials

Any topic without an identifiable topic name on the platform

Angular
Cloud Hosting

3 Tutorials

arrow_right
Angular
Cloud Hosting

3 Tutorials

Cloud computing is the on-demand availability of computer system resources, especially data storage and computing power, without direct active management by the user.

Angular
Heroku

1 Tutorials

arrow_right
Angular
Heroku

1 Tutorials

Heroku is a cloud platform as a service supporting several programming languages. One of the first cloud platforms,

Angular
Shell Scripting

1 Tutorials

arrow_right
Angular
Shell Scripting

1 Tutorials

A shell script is a computer program designed to be run by the Unix shell, a command-line interpreter. The various dialects of shell scripts are considered to be scripting languages.

Angular
Docker

1 Tutorials

arrow_right
Angular
Docker

1 Tutorials

Docker is a set of platform as a service products that use OS-level virtualization to deliver software in packages called containers.

Angular
Ansible

1 Tutorials

arrow_right
Angular
Ansible

1 Tutorials

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems.

KtechHub

KtechHub is an e-learning platform where individual learn and share knowledge with others.

Follow Us

Terms Privacy policy

Copyright 2020 © All rights reserved.