Project Deployment Process

Solving problems through digital solutions

We at Kutia have 3 environments for each project:

  • Local (Developer’s PC)
  • Staging/Testing (Our in-house staging server)
  • Production

We also use git to control/keep track of our code.

In order for the developers to push their code to the Staging server, we use a deployment process to enable the developers to only run git push staging or as we like to refer to it as kutia84 πŸ˜› , and have their latest code running on an actual server and ready to be tested.

To make that command work we have a setup process.

I used a Laravel Application as a project example, it is basically the same process for other types of projects as well.

Server Setup:

First we need a server, ours is running on (This will be our Staging server):
Ubuntu 18.04.2 LTS.

Currently we use PHP(Laravel and WordPress) and Javascript(Node.JS, React.js,…) on our projects. So we will need Nginx/Apache Server, PHP and Node installed on our Server.

As for the databases side we mostly use SQL databases so we have MySQL and PostgreSQL installed.

Here is a link on how to get up and running with NGINX, PHP and MySQL on your server:

How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 18.04

Setup git push staging:

First you need to ssh into your server:

$ ssh root@[SERVER_IP]

Now we need to install git on the server if you don’t already have it:

$ sudo apt update
$ sudo apt install git

Then we need to clone our repository to our server’s public_html usually located under /var/www/public_html :

$ cd /var/www/public_html
$ git clone [REPOSITORY_URL_HERE]

Now that we have cloned our repository, we will run our necessary setup commands. In our case, since this is a laravel, app we will need to run:

$ composer install
$ npm install
$ npm run development 
// development or production depending on your environment

Now that we have setup our Laravel App, we will create the bare repository so we can push the changes from our local PC.

Usually, we at Kutia, put our Bare repos under /var/www/deploy .

Create the deploy directory:

$ mkdir /var/www/deploy
$ cd /var/www/deploy

Clone the bare repo:

Repositories cloned with git cloned [URL] --bare are called bare repos. They are structured a bit differently from working directories. First off, they contain no working or checked out copy of your source files. [LINK]

$ git clone [REPOSITORY_URL_HERE] --bare

This will create a directory inside of /var/www/deploywith the repositories name ending with .git.

Now, for this repo to receive the commits when you dogit push staging, we need to a create post-receive file which tells where the work tree is and checkout.

$ cd /var/www/deploy/[YOUR_BARE_REPO]/hooks
$ vi post-receive

Add this inside the post-receive file:

#!/bin/sh
# The GIT_WORK_TREE path will be the path of your project root
GIT_WORK_TREE=/var/www/public_html/[REPO] git checkout -f

Then, save it 🀞.
If you have problems closing vim πŸ˜‚ (we all did at some point), here is a link: CLOSE VIM editor

Nice job πŸ˜‚πŸ˜‚.
WOW! FUNNY GUY.

Now we need to allow execution of this script:

$ chmod +x /var/www/deploy/[YOUR_BARE_REPO]/hooks/post-receive

Finally you are done on the server side 🀞.

Now, on you local pc, go to your repository:

$ cd [YOUR repository path]

Add the new staging remote:

$ git remote add staging root@[YOUR_IP]:/var/www/deploy/[YOUR_BARE_REPO]

πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰

Now you should be able to simply do:

$ git push staging

And your local commits will be pushed to the staging server.

Extra… detect asset changes on push

On our deployment process we also use one more hook so that when we push our commits to staging, we can check if there are changes on composer.json or package.json to run composer install or npm install respectively.

We also check if we have changes on the javascript files so we can run npm run development or production to compile our assets.

Checking for src file changes

First ssh into the server.

We need to create 2 more hooks on the bare repo: post-merge and post-checkout but they will contain the same content.

First, we will check if we actually have node_modules on our project:

# This checks if node_modules directory exists, if not it runs npm install
# this usually runs only the first time.

WORK_TREE_DIR="/var/www/public_html/[REPO]"

if [ ! -d "$WORK_TREE_DIR/node_modules" ]; then
    echo "Running npm install"
    npm install
    echo "npm install DONE."
fi

We also need to know if there are any changes on the /src files or in Laravel’s case /resources/assets.

# This will check if there are any changes on the 'resources/assets',
# and the run the compile script 'npm run development'

changed_files="$(git diff-tree -r --name-only --no-commit-id HEAD~ HEAD)"

echo "$changed_files" | grep --quiet "resources/assets" &&
echo "Changes to 'resources/assets' detected" &&
cd "$WORK_TREE_DIR" &&
npm run development &&
echo "Assets compiled"

Here is the complete file:

#!/bin/sh

changed_files="$(git diff-tree -r --name-only --no-commit-id HEAD~ HEAD)"
WORK_TREE_DIR="/var/www/public_html/[REPO]"

run_npm_on_resources_folder_change() {
    echo "$changed_files" | grep --quiet "resources/assets" &&
    echo "Changes to 'resources/assets' detected" &&
    cd "$WORK_TREE_DIR" &&
    check_if_node_modules_exist &&
    echo "Started compiling assets..." &&
    npm run development &&
    echo "Assets compiled"
}

check_if_node_modules_exist() {
    if [ ! -d "$WORK_TREE_DIR/node_modules" ]; then
        echo "Running npm install"
        npm install
        echo "npm install DONE."
    fi
}

run_gulp_on_src_folder_change

exit 0;

Put that inside of:

  • /var/www/deploy/[YOUR_BARE_REPO]/hooks/post-merge and
  • /var/www/deploy/[YOUR_BARE_REPO]/hooks/post-checkout

Run:

$ chmod +x /var/www/deploy/[YOUR_BARE_REPO]/hooks/post-merge
$ chmod +x /var/www/deploy/[YOUR_BARE_REPO]/hooks/post-checkout

To allow execution of these 2 files.

Now you’re all setup so when you do git push staging on your local PC:

  • Your commits will be pushed to the staging server
  • If the node_modules directory doesn’t exist on the server npm install will run.
  • If there are any asset changes npm run development will run to compile the assets.

You can put your checks for package.json or composer.json changes in the post-merge and post-checkout files.

If you think you can help us build a better deployment process, we are looking for a DevOps Engineer.

Apply here πŸ™‚