Deployment of Laravel app on DigitalOcean / Ubuntu server

In this tutorial, we’ll learn how to deploy Laravel 8 app on DigitalOcean droplet. This tutorial assumes that you have already set up the droplet server using Ubuntu 18.04 LTS (any other Ubuntu version should do just fine) and installed MySQL, Nginx, PHP7.4 (Laravel 8 requires PHP 7.3+ version) along with Composer. And you’ve ssh’d into the server.

MySQL

First, let’s create a new database in MySQL and assign user rights to use it. Enter the following command to run MySQL client using root user:

mysql -u root -p

Enter root MySQL password. Once inside MySQL client, execute following command to create a new database:

create database db;

A new database named ‘db’ has just been created. Now, you can use username ‘root’ and root’s MySQL password in .env file Laravel app in order to connect to database from Laravel app. However, it’s advisable that a separate user, instead of root, be used to connect to database. So for this purpose, choose another user e.g. sohail, then assign user rights to this user by entering following command in MySQL client:

grant all on db.* TO 'sohail'@'localhost' identified by 'password' with grant option;

Now flush privileges by entering following command in MySQL client:

flush privileges;

It’s done at the database side. Now exit MySQL client by entering following command:

exit

Laravel

If not already, then move on to home directory by entering following command at the ssh’d shell prompt of your server:

cd ~/

Now clone a Laravel repository by entering git clone command e.g.

git clone https://github.com/SohailSal/mzerp.git

This command will create a directory named ‘mzerp’ and clone the repository into this newly created directory. You should rename the folder by entering your domain name e.g.

mv mzerp mydomain.com

Now move into directory my entering:

cd mydomain.com

Copy settings file by entering following command:

cp .env.example .env

Open .env file by entering:

nano .env

Replace settings of database in .env file accordingly e.g.

APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=db
DB_USERNAME=sohail
DB_PASSWORD=password

You’d also need to change app settings in production deployment e.g. APP_DEBUG should be ‘false’ (You wouldn’t want your webapp users to see whole trails of errors). Likewise APP_URL should be your domain URL and APP_ENV should be replaced with ‘production’ instead of ‘local’. You can save changes in nano editor by pressing CTRL+O then pressing Enter when prompts and exit by pressing CTRL+X.

Now execute the following command in app directory to install the Laravel app dependencies:

composer install

Next execute the following command to generate and insert unique key to .env file:

php artisan key:generate

Finally, create tables into the database by executing following command:

php artisan migrate

Nginx

First, come out of app directory by entering following command:

cd ..

Now, move app folder to /var/www location:

sudo mv mydomain.com /var/www

Next, change ownership of your app’s storage and cache folders by executing following commands:

sudo chown -R www-data.www-data /var/www/mydomain.com/storage
sudo chown -R www-data.www-data /var/www/mydomain.com/bootstrap/cache

Now, we move onto nginx configuration. First, create a new virtual host configuration file at /etc/nginx/sites-available folder:

sudo touch /etc/nginx/sites-available/mydomain.com

You may use nano as mentioned above to edit this newly created file:

sudo nano /etc/nginx/sites-available/mydomain.com

Now copy paste the following code into this file:

server {
    listen 80;
    listen [::]:80;

    server_name mydomain.com www.mydomain.com;
    root /var/www/mydomain.com/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;
    }
}

Save and exit as usual (CTRL+O, Enter, CTRL+X).

Finally, create a symbolic link to this file in /etc/nginx/sites-enabled/ folder:

sudo ln -s /etc/nginx/sites-available/mydomain.com /etc/nginx/sites-enabled/

Restart Nginx web server by entering following command:

sudo systemctl reload nginx

DNS Settings

You would also need to make some required DNS settings.

If you are hosting multiple domains on same droplet (same ip address), you’d need to change /etc/hosts file as follows:

127.0.0.1 localhost
127.0.0.1 mydomain.com
127.0.0.1 myseconddomain.com

If you haven’t already changed nameservers with your domain manager (e.g. godaddy), do it by customizing nameservers in Domain Management option and inserting the nameservers provided by DigitalOcean.

Finally, log in to your DigitalOcean account, go to Create, select Domains option and register your domain there. Then go to Manage domain option just next to newly inserted domain and enter two DNS A records there i.e. @ and www records.

That’s it! The world will see your creation now…of course, be patient for few hours for DNS propagation.

Leave a Comment