Project Deployment Process
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-mergeand/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_modulesdirectory doesn’t exist on the servernpm installwill run. - If there are any asset changes
npm run developmentwill 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.