Simple deployment strategy using only git + ssh + vpn

  • There is a staging environment and a production environment
  • The environments are set up on two different servers
  • The servers reside in a VPC, hence their consoles are only accessible via a VPN
  • There is a build step which will be run on the servers before the actual deployment will take place

Setting up users (remote)

Setting up the repositories (remote)

cd /var/git
sudo mkdir MyProject
sudo chown deployer: MyProject
cd MyProject
git init --bare
#!/usr/bin/env bashgit --work-tree=/tmp/MyProject --git-dir=/var/git/MyProject checkout -f

Setting up the development environment (local)

cd ~/Workspace/MyProject
git remote add staging ssh://deployer@staging-server/var/git/MyProject
git remote add production ssh://deployer@production-server/var/git/MyProject
cd ~/.ssh
vi config
Host staging-server
HostName staging-server
Identityfile /home/claudioc/.ssh/staging.pem
Host production-server
HostName production-server
IdentityFile /home/claudioc/.ssh/production.pem
git push staging master
  • once the files are in checked out, I run `npm install` and `npm prune`
  • once the npm install is finished, I run my tests with `npm test`
  • if all the test pass, I run `gulp build`
  • if the build is successful, I will `rsync` the `/dist` directory in the directory which is served by the web server

Bonus (bullet) points

  • stdout output from the `post-receive` hook is sent back to the console where the “git push” has been started from. This means that you are able to see what’s going on during the deployment (and use `echo` statements to make it even more verbose)
  • the user with which the `post-receive` script is run is the owner of the script itself. Keep this in mind when you are setting up the directories and which commands to run from the script
  • to be able to run the post-receive script even if there is nothing to push, an interesting option is to delete the master branch on the server (from inside the post-receive script itself: `rm -rf /var/git/MyProject/refs/heads/master` (it will add more transfer time, of course)
  • in this simple setup there isn’t a robust and automated rollback strategy. My suggestion is to always tag your repo before pushing. If you find problems with the current version, “rolling back” to the previous tag would be just a matter of:
cd ~/Workspace/MyProject
git reset MyPreviousTag --hard
git push -f staging master
git pull origin master

Further readings




My specialties are software engineering, fintech and pointless random rants. I live in Berlin.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Claudio Cicali

Claudio Cicali

My specialties are software engineering, fintech and pointless random rants. I live in Berlin.

More from Medium

How to Install PostgreSQL on Windows and run it from CMD

The GridWhale File System

Docker to the rescue

Search/Indexing JSON documents