Skip to main content

7 easy steps to automated git push deployments.

---
title: How-to setup a simple git push deployment
subtitle: "7 easy steps to automated git push deployments."
author: Thomas Fritz
date: April 11, 2017
source: https://gist.github.com/thomasfr/9691385
notoc: false
---

# How-to setup a simple git push deployment

These are my notes basically. At first i created this gist just as a reminder
for myself. But feel free to use this for your project as a starting point. If
you have questions you can find me on twitter @thomasf
<https://twitter.com/thomasf>

This is how i used it on a Debian Wheezy testing <https://www.debian.org/releases/testing/>

Discuss, ask questions, etc. here <https://news.ycombinator.com/item?id=7445545>

## On the server (example.com)

1. Create a user on `example.com`, as which we (the git client) connect (push)
   to `exmaple.com`. We set `git-shell` as the login shell, so it is not
   possible to interactively login as this user.

```bash
sudo useradd -m -s /usr/bin/git-shell git
```

2. Add your ssh public key to the `authorized_keys` file of the created user:

```bash
## Because user git can not interactively login, we have to use sudo to get git temporarily
sudo -u git bash
cd ~
## cd /home/git
mkdir -p .ssh
vim .ssh/authorized_keys
## Paste your public key and save
```

3. Create a `git bare` repo for your project:

```bash
mkdir testapp
cd testapp
## /home/git/testapp
git init --bare
```

4. Copy the `post-receive` script from this gist to the `hooks` dir of the created bare repo.

```bash
vim testapp/hooks/post-receive
## Paste the post-receive script from this gist and save
## If you do not need to execute a 'build' and/or 'restart' command,
## just delete or comment the lines 'UPDATE_CMD' and 'RESTART_CMD'
chmod +x testapp/hooks/post-receive
```

5. Set ownership and permissions of the `DEPLOY_ROOT` directory:

```bash
sudo chown root:git -R /var/www
sudo chmod 775 /var/www
```

- (**Optional**) Add a systemd service file for your app. If you are using
  `systemd`, you can use the `testapp.service` file from this gist. Make sure
  you name it like your repository. The post-receive hook can automatically
  restart your app. You will also have to allow user git to make the `sudo`
  call. Be very careful and restrictive with this!

## On the client

6. Create a git repo and add our newly created `remote`:

```bash
mkdir testapp
cd testapp
git init
git remote add production git@example.com:~/testapp
```

7. Commit and push to production:

```bash
$ vim Makefile
## Paste contents of Makefile from this gist (as an example)
$ git add .
$ git commit -am "test commit"
$ git push production master
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 432 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: +++++++++++++++++++++++ Welcome to 'example.com' (1.2.3.4) ++++++++++++++++++++++++
remote:
remote: githook: I will deploy 'master' branch of the 'testapp' project to '/var/www/testapp'
remote:
remote: githook: UPDATE (CMD: 'cd "${DEPLOY_TO}" && make "update"'):
remote: Makefile: Doing UPDATE stuff like grunt, gulp, rake,...
remote: git
remote: /var/www/testapp
remote:
remote: githook: RESTART (CMD: 'sudo systemctl restart "${PROJECT_NAME}.service" && sudo systemctl status "${PROJECT_NAME}.service"'):
remote: testapp.service - node.js testapp
remote:    Loaded: loaded (/etc/systemd/system/testapp.service; disabled)
remote:    Active: inactive (dead) since Fri 2014-03-21 22:10:23 UTC; 10ms ago
remote:   Process: 9265 ExecStart=/bin/bash -c sleep 3;echo "I am starting";echo "$(whoami)"; (code=exited, status=0/SUCCESS)
remote:
remote: Mar 21 22:10:20 image systemd[1]: Starting nodejs testapp...
remote: Mar 21 22:10:23 image testapp[9265]: I am starting
remote: Mar 21 22:10:23 image testapp[9265]: www-data
remote: Mar 21 22:10:23 image systemd[1]: Started node.js testapp.
remote:
remote: ++++++++++++++++++++ See you soon at 'example.com' (1.2.3.4) ++++++++++++++++++++++
To git@example.com:~/testapp
   08babc4..95cabcc  master -> master

```

- **Repeat:** Develop, test, commit and push :)

```bash
make deploy
```

_Congratulations, you just setup git push deployment with automated build and service restart_

Here are some more configuration files as a starting point:

- [NGINX reverse proxy to local service running on non-privileged port (e.g. node.js)](https://gist.github.com/thomasfr/8653547)
- [A common set of iptable rules](https://gist.github.com/thomasfr/9712418)
- [A systemd service file for autossh (keeps an ssh tunnel open)](https://gist.github.com/thomasfr/9707568)
- [Warmly - a poor mans wget based cache warmer script](https://gist.github.com/thomasfr/7926314)