SFTP, SCP, Rsync, the good old FTP – there are many ways to deliver an app. The choice depends on many factors, such as working speed, infrastructure limitations (some servers allow only FTP upload), or developer preferences.
Some time ago we made an analysis of what our clients use for application upload. The clear winner was the FTP protocol. Right after it, there were SFTP and Rsync. However, in this post we’d like to talk about the fourth contender that only just missed the podium: Git.
INFO: The strong position of FTP most probably results from its popularity among WordPress and PHP developers and the fact that many servers don’t allow any other upload option. However, the protocol has one big flaw: front-end apps contain a lot of files and uploading them can take a long time.
TIP: Buddy uploads only those files that were changed, which significantly shortens the upload time.
Git deployment
Every developer knows Git. If you want to pull the latest version of the repo, you run git pull
. If you want to share changes with others, you run git push
. And since only changesets are uploaded, these operations are very fast. However, many people don’t know that they can deploy apps in the same way. In this article, we’ll describe how to configure a server to release an application with git push
/pull
.
Before we get down to business, though, let’s remember one important rule:
WARNING: Never keep dependencies and compiled artifacts in the repo!
If you’d like to learn why (and you should), we’ve covered it in detail in this article.
Git pull
In this case, we have a clone of our repo on the server where the app is run. When we want to release a new version, we execute git pull
there to fetch the latest version of the app.
Setup
Frist, install SSH and Git on the server:
$ sudo apt-get install -y openssh-server git
Now, create a folder from which we’ll serve our app, and initiate git repo in it:
$ mkdir ~/www/app.com
$ cd ~/www/app.com
$ git init
The last thing is adding the remote to our repo and pulling the application:
git remote add origin URL
git pull master
TIP: The best practice is to create a new user on the server and grant him/her access to the Git repo (GitHub/Bitbucket/GitLab, etc.). Here’s a good tutorial how to do it.
If our application requires building (fetch dependencies, compile assets, generate artifacts, etc.), we’ll execute the build commands manually on the server (npm, composer, yarn install, gulp grunt webpack, etc.).
Release
Every time we want to release our app, we connect to the server and execute git pull
and the build commands there.
Rollback is very easy, too: all you need to do is checkout the revision to which you want to return, and build the app again.
Git push
In the previous use-case, we connected to the server first and executed commands later. Now we’ll learn how to make a release with locally executed git push
.
Setup
Just like with the ‘git pull’ use-case, we need a server with SSH and Git installed:
$ sudo apt-get install -y openssh-server git
Create a folder from which we’ll serve our app, and initiate git repo in there:
$ mkdir ~/www/app.com
$ cd ~/www/app.com
$ git init
Now we need to configure Git to allow for ref update to the currently checked out branch and set the worktree to the directory with the repo:
$ git config receive.denycurrentbranch ignore
$ git config core.worktree ~/www/app.com
The last thing is setting a post-receive hook. It’ll check out the new version of the repo and build the app if needed.
Go to edit mode
$ nano .git/hooks/post-receive
and set the scripts:
# !/bin/sh
# checkout HEAD
git checkout -f
# fetch dependencies and build
npm install
gulp
Finally, we set the permissions to the file:
$ chmod +x .git/hooks/post-receive
Done! The rest we’ll do locally.
Release
We’ll deploy the new version of the app right from our repo. All we need to do is add a proper remote to it (let’s call it ‘Production’):
$ cd ~/repos/myrepo
$ git remote add production ssh://user@ip/home/user/www/app.com
INFO: The authorization is performed with SSH. In our case, it’s the same user that we used to perform the setup.
To release the application, just execute:
$ git push production master
Pros and Cons of Git deployment
The major pro is definitely the release time of every next version of the application: it’s fast because only changesets are pulled.
On the other hand, the main disadvantage of deploying with Git is that the app needs to be built on the server. This extends the downtime because we have to wait until the dependencies are pulled and the build performed. Moreover, in both cases we need to remember to test the app before the deployment.
TIP: We have described how to create mechanisms that will shorten the application downtime here.