Deploy Laravel applications with GitLab CI/CD and Envoy

Khairu Aqsara Sudirman

Khairu Aqsara Sudirman

Feb 23, 2021 — 8 mins read

GitLab features our applications with Continuous Integration, and it is possible to easily deploy the new code changes to the production server whenever we want. In this tutorial, I’ll show you how to initialize a Laravel application and set up our Envoy tasks, then we’ll jump into see how to test and deploy it with GitLab CI/CD via Continuous Delivery. I assume you have a basic experience with Laravel, Linux servers, and you know how to use GitLab.

Laravel is a high quality web framework written in PHP. It has a great community with a fantastic documentation. Aside from the usual routing, controllers, requests, responses, views, and (blade) templates, out of the box Laravel provides plenty of additional services such as cache, events, localization, authentication, and many others.

We will use Envoy as an SSH task runner based on PHP. It uses a clean, minimal Blade syntax to set up tasks that can run on remote servers, such as, cloning your project from the repository, installing the Composer dependencies, and running Artisan commands

Configure the production server

Before we begin setting up Envoy and GitLab CI/CD, let’s quickly make sure the production server is ready for deployment. We have installed LEMP stack which stands for Linux, NGINX, MySQL, and PHP on our Ubuntu 16.04

Create a new user

Let’s now create a new user that will be used to deploy our website and give it the needed permissions using Linux ACL

sudo adduser deployer
sudo setfacl -R -m u:deployer:rwx /var/www

If you don’t have ACL installed on your Ubuntu server, use this command to install it:

sudo apt install acl

Add SSH key

Let’s suppose we want to deploy our app to the production server from a private repository on GitLab. First, we need to generate a new SSH key pair with no passphrase for the deployer user. After that, we need to copy the private key, which will be used to connect to our server as the deployer user with SSH, to be able to automate our deployment process:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
cat ~/.ssh/id_rsa

Now, let’s add it to your GitLab project as a CI/CD variable. Project CI/CD variables are user-defined variables and are stored out of .gitlab-ci.yml, for security purposes. They can be added per project by navigating to the project’s Settings > CI/CD.

We also need to add the public key to Project > Settings > Repository as a Deploy Key, which gives us the ability to access our repository from the server through SSH protocol.

cat ~/.ssh/id_rsa.pub

To the field Title, add any name you want, and paste the public key into the Key field.

Now, let’s clone our repository on the server just to make sure the deployer user has access to the repository.

git clone git@gitlab.example.com:<USERNAME>/laravel-sample.git

Answer yes if asked Are you sure you want to continue connecting (yes/no)?. It adds GitLab.com to the known hosts.

Configuring NGINX

Now, let’s make sure our web server configuration points to the current/public rather than public. Open the default NGINX server block configuration file by typing:

sudo nano /etc/nginx/sites-available/default

The configuration should be like this.

server {
    root /var/www/app/current/public;
    server_name example.com;
    # Rest of the configuration
}

You may replace the app’s name in /var/www/app/current/public with the folder name of your application

Setting up Envoy

So we have our Laravel app ready for production. The next thing is to use Envoy to perform the deploy. To use Envoy, we should first install it on our local machine using the given instructions by Laravel

@servers(['web' => 'deployer@contoh.com'])
@setup
    $app_dir = '/home/aplikasi/www/laravel';
@endsetup
@story('deploy')
    update_sources_dari_gitlab
    clean_cache_laravel
@endstory
@task('update_sources_dari_gitlab')
    echo '[+] Sedang Mengupdate Repository'
    cd {{ $app_dir }}
    git pull origin master
    echo '[!] Update Selesai'
@endtask
@task('clean_cache_laravel')
    echo '[+] Membersihkan Cache Aplikasi'
    cd {{ $app_dir }}
    php artisan optimize:clear
    echo '[!] Cache Aplikasi sudah dibersihkan'
@endtask 

Continuous Integration with GitLab

We have our app ready on GitLab, and we also can deploy it manually. But let’s take a step forward to do it automatically with Continuous Delivery method. We need to check every commit with a set of automated tests to become aware of issues at the earliest, and then, we can deploy to the target environment if we are happy with the result of the tests.

GitLab CI/CD allows us to use Docker engine to handle the process of testing and deploying our app. In case you’re not familiar with Docker, refer to Set up automated builds

To be able to build, test, and deploy our app with GitLab CI/CD, we need to prepare our work environment. To do that, we’ll use a Docker image which has the minimum requirements that a Laravel app needs to run. There are other ways to do that as well, but they may lead our builds run slowly, which is not what we want when there are faster options to use

Create a Container Image

FROM php:7.4
RUN apt-get update
RUN apt-get install -qq git curl libmcrypt-dev libbz2-dev libzip-dev
RUN apt-get clean
RUN docker-php-ext-install zip
RUN curl --silent --show-error "https://getcomposer.org/installer" | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer global require "laravel/envoy"

We added the official PHP 7.4 Docker image, which consist of a minimum installation of Debian buster with PHP pre-installed, and works perfectly for our use case. We used docker-php-ext-install (provided by the official PHP Docker image) to install the PHP extensions we need

Setting Up GitLab Container Registry

The registry is the place to store and tag images for later use. Developers may want to maintain their own registry for private, company images, or for throw-away images used only in testing. Using GitLab Container Registry means you don’t need to set up and administer yet another service or use a public registry. On your GitLab project repository navigate to the Registry tab.

You may need to enable the Container Registry for your project to see this tab. You’ll find it under your project’s Settings > General > Visibility, project features, permissions. To start using Container Registry on our machine, we first need to sign in to the GitLab registry using our GitLab username and password. Make sure you have Docker installed on our machine, then run the following commands:

docker login registry.gitlab.com

Then we can build and push our image to GitLab:

docker build -t registry.gitlab.com/<USERNAME>/laravel-sample .
docker push registry.gitlab.com/<USERNAME>/laravel-sample

Congratulations! You just pushed the first Docker image to the GitLab Registry, and if you refresh the page you should be able to see it:

You can also use GitLab CI/CD to build and push your Docker images, rather than doing that on your machine. We’ll use this image further down in the .gitlab-ci.yml configuration file to handle the process of testing and deploying our app.

Setting up GitLab CI/CD

In order to build and test our app with GitLab CI/CD, we need a file called .gitlab-ci.yml in our repository’s root. It is similar to Circle CI and Travis CI, but built-in GitLab. Our .gitlab-ci.yml file will look like this:

image: registry.gitlab.com/username/2021/kulikode:latest
stages:
  - deploy
deploy_development:
  stage: deploy
  script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh
    - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
    - ~/.composer/vendor/bin/envoy run deploy
  environment:
    name: development
    url: http://contoh.com
  when: manual
  only:
    - master

Deploying

The job deploy_development will deploy the app to the development server. To deploy our app with Envoy, we had to set up the $SSH_PRIVATE_KEY variable as an SSH private key. If the SSH keys have added successfully, we can run Envoy.

As mentioned before, GitLab supports Continuous Delivery methods as well. The environment keyword tells GitLab that this job deploys to the production environment. The url keyword is used to generate a link to our application on the GitLab Environments page. The only keyword tells GitLab CI/CD that the job should be executed only when the pipeline is building the master branch. Lastly, when: manual is used to turn the job from running automatically to a manual action.

You may also want to add another job for staging environment, to final test your application before deploying to production

Turn on GitLab CI/CD

We have prepared everything we need to test and deploy our app with GitLab CI/CD. To do that, commit and push .gitlab-ci.yml to the master branch. It will trigger a pipeline, which you can watch live under your project’s Pipelines.

We configured GitLab CI/CD to perform automated tests and used the method of Continuous Delivery to deploy to production a Laravel application with Envoy, directly from the codebase.

Envoy also was a great match to help us deploy the application without writing our custom bash script and doing Linux magics.

This Article mostly taken from Gtilab Documentation

laravel git php
Read More

PHP Fungsi Terbilang

merubah angka menjadi bentuk terbilang dalam bahasa indonsia dengan php