How to automatically deploy Laravel application on Ubuntu 16.04?


Today using cloud server solution for your website is one of the best solutions for your business. And the reason behind it is that you get a lot of advantages where it will help your business to grow. By using cloud servers for your business you get better security, reliability, scalability and also flexibility.  Not only that using a cloud server for your business will also reduce your IT infrastructure expenditure. So, for this reason, today you can see that a lot of business are using the cloud hosting services.


So today if you are using a website based on a cloud server and if you are looking for information on how to automatically deploy Laravel application on Ubuntu 16.04 then here is the complete information on it.  But before that what is Laravel? Laravel is an open source PHP web framework which is designed to make a common web extension tasks like routing, caching and authentication. And Deployer is also an open source PHP deployment tool where you get support for popular frameworks such as Symfony, CodeIgniter, Laravel etc.


So if you are using a Deployer you no need to install dependencies with Composer and configure it manually it automatically deploy it by cloning with an application from a Git repository to a server. So by using a Deployer on your cloud server, it allows you to spend more time on your development process rather than uploading and configuring.


Here is the information on how to  automatically deploy Laravel application on Ubuntu 16.04:


>> >> First you have to setup your local development environment, so on your local machine/ server you need to download the Deployer and you have to install it by using curl. So to do so follow this command-


$ curl -LO https://deployer.org/deployer.phar


>> Now you need to run a short PHP script and you have to verify that the installer matches the SHA-1 hash for the latest installer found on the Deployer


$ php -r "if (hash_file('sha1', 'deployer.phar') === '35e8dcd50cf7186502f603676b972065cb68c129') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('deployer.phar'); } echo PHP_EOL;"


>> Now you will this output


Output

Installer verified


>> Once you Deployer is verified you need to make sure it is available in system-wide. Note if you are using Windows or Mac OS then you need to create this /usr/local/bin/dep  directory before running the below command


$ sudo mv deployer.phar /usr/local/bin/dep


>> Now make it executable use this code


$ sudo chmod +x /usr/local/bin/dep


>> Once the program is executed now you have to create a  Laravel project on your local machine


$ composer create-project --prefer-dist laravel/laravel laravel-app "5.5.*"


>> >> Now you have to connect to your remote Git repository. And a Deployer is designed to enable it, users, to deploy their code from anywhere. So to allow this function you need to push the code to a  repository on the Internet from which Deployer then copies the code on the server.


>> So now you need to run the following command on your local machine to generate the SSH key.


$ ssh-keygen -t rsa -b 4096 -f  ~/.ssh/gitkey


>> Now create an SSH config file on your local machine by following the below code


$ touch ~/.ssh/config


>> Now you can open the file and you can add a shortcut to your Git server. And here you should give your hostname and the IdentityFile directive


~/.ssh/config

Host mygitserver.com

   HostName mygitserver.com

   IdentityFile ~/.ssh/gitkey


>> Now save and close the file and next you need to restrict the permissions.


$ chmod 600 ~/.ssh/config


>>  Now display the content of your public key file


$ cat ~/.ssh/gitkey.pub


>> Later copy the output and add the public key to your Git server.


>> And now you will be able to connect to your Git server with your local machine.


# ssh -T This email address is being protected from spambots. You need JavaScript enabled to view it.


>> >> Now you have to configure the Deployer user


>> To do that you need to log into your LEMP server with a sudo non-root user and have to create a new username deployer


$ sudo adduser deployer


>> Now the Laravelneeds some writable directories to store cached files and uploads so that the directories are writable by the Nginx web server.


$ sudo usermod -aG www-data deployer


>> Now you have to do this deployer's default umask to 022 setting


$ sudo chfn -o umask=022 deployer


>> If you have stored the app in the  /var/www/html/ directory, you can change that ownership of the directory to the deployer user


$ sudo chown deployer:www-data /var/www/html


>> Now the deployer user needs to be able to modify files and folders within the /var/www/html directory.


$ sudo chmod g+s /var/www/html


>> Now Switch to the deployer user on your server:


$ su - deployer


>> Now you need to generate an SSH key pair as the  deployer user


$ ssh-keygen -t rsa -b 4096


>> Now display the public key:


cat ~/.ssh/id_rsa.pub


>> And now on your local machine you need to run the below command to replace deployer key to your choice


$ ssh-keygen -t rsa -b 4096 -f  ~/.ssh/deployerkey


>> Now copy the following command's output which contains the public key:


$ cat ~/.ssh/deployerkey.pub


>> And now on your server as the deployer user run the belwo command


$ nano ~/.ssh/authorized_keys


>> Now you need to restrict the permissions of the file:


$ chmod 600 ~/.ssh/authorized_keys


>> Now switch back to the sudo user:


$ exit


>> Now log in from your local machine to you server


$ ssh deployer@your_server_ip  -i ~/.ssh/deployerkey


>> Now you conduct a test connection on your server and the Git server


$ ssh -T This email address is being protected from spambots. You need JavaScript enabled to view it.


>> Finally, exit the server:


exit


>> >> Now you have to Configure Nginx


>> First log into your server as you are a sudo user and create a new config file.


$ sudo nano /etc/nginx/sites-available/testdomain.com


>> Now add a server block to the top of the configuration file:


testdomain.com '>/etc/nginx/sites-available/testdomain.com


server {

       listen 80;

       listen [::]:80;


       root /var/www/html/laravel-app/current/public;

       index index.php index.html index.htm index.nginx-debian.html;


       server_name testdomain.com www.testdomain.com;

}


>> Here you should also modify the way that Nginx will handle requests and this is done through the try_files directive


testdomain.com '>/etc/nginx/sites-available/testdomain.com


server {

       listen 80;

       listen [::]:80;


       root /var/www/html/laravel-app/current/public;

       index index.php index.html index.htm index.nginx-debian.html;


       server_name testdomain.com www.testdomain.com;


       location / {

               try_files $uri $uri/ /index.php?$query_string;

       }


>> In here you need to create a block that handles the actual execution of any PHP files. And this will apply to any files that end up in .php.


server {

       listen 80;

       listen [::]:80;


       root /var/www/html/laravel-app/current/public;

       index index.php index.html index.htm index.nginx-debian.html;


       server_name testdomain.com www.testdomain.com;


       location / {

               try_files $uri $uri/ /index.php?$query_string;

       }



       location ~ \.php$ {

               include snippets/fastcgi-php.conf;


               fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

               fastcgi_param DOCUMENT_ROOT $realpath_root;


               fastcgi_pass unix:/run/php/php7.0-fpm.sock;


       }


>> Once after adding the  location block you need to configure the file and it will look like this


testdomain.com '>/etc/nginx/sites-available/testdomain.com


server {

       listen 80;

       listen [::]:80;


       root /var/www/html/laravel-app/current/public;

       index index.php index.html index.htm index.nginx-debian.html;


       server_name testdomain.com www.testdomain.com;


       location / {

               try_files $uri $uri/ /index.php?$query_string;

       }



       location ~ \.php$ {

               include snippets/fastcgi-php.conf;


               fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;

               fastcgi_param DOCUMENT_ROOT $realpath_root;


               fastcgi_pass unix:/run/php/php7.0-fpm.sock;


       }


       location ~ /\.ht {

               deny all;

       }


}


>> Now save and close the file and then enable the new server  block by creating a symbolic link to the sites-enabled directory


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


>> Now test your configuration file for syntax errors


$ sudo nginx -t


>> If there is any errors then go back and recheck your file. And later restart the Nignix to push the necessary changes


$ sudo systemctl restart nginx


>> Now you have to configure MySQL. So log in to the MySQL console as root


$ mysql -u root -p


>> Now create a new database for that application


mysql> CREATE DATABASE laravel_database DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;


>> Once after creating a new database create a password


mysql> CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';


>> Now you need to grant privileges on the database to the user:


mysql> GRANT ALL ON laravel_database.* TO 'laravel_user'@'localhost';


>> Now, reload the privileges:


mysql> FLUSH PRIVILEGES;


>> And, finally, exit from the MySQL console


mysql> EXIT;


>> >>  Deploying the Application now you need to open the terminal on your local machine and change the working directory to the application's folder with the following command:


$ cd /path/to/laravel-app


>> Now from this directory you need to run the below command where it creates a file called deploy.php


$  dep init -t Laravel


>> Now, open the deploy.php file with your preferred text editor or IDE.

deploy.php


<?php

namespace Deployer;


require 'recipe/laravel.php';


. . .


>> And once when you are donw editing it will look like this


deploy.php

...

// Project name

set('application', 'laravel-app');


// Project repository

set('repository', This email address is being protected from spambots. You need JavaScript enabled to view it.:username/repository.git');


. . .


// Hosts


host('your_server_ip')

   ->user('deployer')

   ->identityFile('~/.ssh/deployerkey')

   ->set('deploy_path', '/var/www/html/laravel-app');


>> Next, comment out the last line of the file, before('deploy:symlink', 'artisan:migrate');. This line trains Deployer to run the database movements consequently, and by remarking it out we are crippling it.


deploy.php

...

// Migrate database before symlink new release.


//before('deploy:symlink', 'artisan:migrate');


>> Now on your local machine change the working directory to your application's folder


$  cd /path/to/laravel-app


>> Now run the  following command in your laravel-app directory to initialize a Git repository in the project folder


$  git init


>> Now add all the project files to the repository:


$  git add .


>> And you also need to commit the changes:


$  git commit -m 'Initial commit for first deployment.'


>> You need to add your Git server to the local repository with the below command.


$ git remote add origin This email address is being protected from spambots. You need JavaScript enabled to view it.:username/repository.git


>> Now push the changes to the remote Git repository:


$  git push origin master


>> Finally, run your first deployment using the dep


$  dep deploy


>> Now you will see the below output on your screen


Deployer's output


✈︎ Deploying master on your_server_ip

✔ Executing task deploy:prepare

✔ Executing task deploy:lock

✔ Executing task deploy:release

➤ Executing task deploy:update_code

✔ Ok

✔ Executing task deploy:shared

✔ Executing task deploy:vendors

✔ Executing task deploy:writable

✔ Executing task artisan:storage:link

✔ Executing task artisan:view:clear

✔ Executing task artisan:cache:clear

✔ Executing task artisan:config:cache

✔ Executing task artisan:optimize

✔ Executing task deploy:symlink

✔ Executing task deploy:unlock

✔ Executing task cleanup

Successfully deployed!


>> Now you need to verify it by running the below command on your server.


$  ls /var/www/html/laravel-app


Output

current  .dep releases  shared


>> Now you need configure the application on your server. So log in to your server as the deployer user


$  ssh deployer@your_server_ip  -i ~/.ssh/deployerkey


>> Now run the below command and paste your local .env file to edit


$  nano /var/www/html/laravel-app/shared/.env


>> Before you can save it, there are some changes that you should make and you have to set APP_ENV to production, APP_DEBUG to false, APP_LOG_LEVEL to error. And never forget to replace the database.


/var/www/html/laravel-app/shared/.env


APP_NAME=Laravel

APP_ENV=production

APP_KEY=base64:cA1hATAgR4BjdHJqI8aOj8jEjaaOM8gMNHXIP8d5IQg=

APP_DEBUG=false

APP_LOG_LEVEL=error

APP_URL=http://example.com


DB_CONNECTION=mysql

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=laravel_database

DB_USERNAME=laravel_user

DB_PASSWORD=password


BROADCAST_DRIVER=log

CACHE_DRIVER=file

SESSION_DRIVER=file

QUEUE_DRIVER=sync


REDIS_HOST=127.0.0.1

REDIS_PASSWORD=null

REDIS_PORT=6379


>> Now save the file and close the editor.  And now uncomment the last line of the deploy.php file on your local machine


deploy.php

...

// Migrate database before symlink new release.


before('deploy:symlink', 'artisan:migrate');


>> So now to check the  configuration is working or not deploy the application once more


$  dep deploy


>> >> Running a typical deployment. In the last step, you need to start it by modifying the application before you deploy again.



>>> As a final step, this section will cover a simple deployment process you can use on a daily basis.


/routes/web.php

<?php


. . .


Route::get('/', function () {

   return view('welcome');

});


Route::get('/greeting', function(){

   return 'Welcome!';

});


>> Now you need to commit these changes


git commit -am 'Your commit message.'


>> Now also need to push the changes on the  remote Git repository


git push origin master


>> Now finally, deploy the application


dep deploy