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.

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.

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:

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.


First, 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

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.).


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.


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

Finally, we set the permissions to the file:

$ chmod +x .git/hooks/post-receive

Done! The rest we'll do locally.


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

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.

We have described how to create mechanisms that will shorten the application downtime here.