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/deploy
with 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 servernpm 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.