Setup a Git Server and Deploy with Git Hooks on Ubuntu 18.04

Table of Contents


In this post we look at the process of setting up a Git repository on a DigitalOcean droplet running Ubuntu 18.04. After setting up the repository, we create a server side hook to automatically deploy a successful git push to a web server. A non-root user with no sudo permissions will be used to create the Git repository. The Git user will also be granted read and write permissions on the website for a successful deployment. After the process of setting up and deploying the repository is complete, we will disable interactive shell for the Git user.


In order to follow along in this post, you will require the following:

  • A server running on Ubuntu 18.04 or higher
  • A user with sudo permissions to connect to the server using SSH. We will use this user to setup the Git user.
  • An installation of Git on the server
  • A directory to deploy the Git repository on a successful git push

Login to Server Using SSH Keys

Using SSH (Secure SHell) log into your DigitalOcean server. You can SSH the server using either the server IP address or your domain name.

  • Using an IP address

      ssh kagundajm@ -i ~/.ssh/kagundajm-droplet
  • Using a domain name. You must configure your domain to point to DigitalOcean before you using the domain name.

      ssh -i ~/.ssh/kagundajm-droplet

Create Git Repository Owner

Create non sudo git user with a disabled password. Logins will only be possible using SSH keys and not passwords.

sudo adduser --disabled-password git

Create File For Authorized SSH Keys

Switch user to the newly create repository owner

sudo su git

Move to home directory of the repository owner


Create directory for SSH key files with read, write and execute for the owner

mkdir ~/.ssh

chmod 700 ~/.ssh

Create authorized keys file with read/write permissions for the owner

touch ~/.ssh/authorized_keys

chmod 600 ~/.ssh/authorized_keys

Create your project repository folder. These steps have to be repeated for all the projects you want to host as repositories.

mkdir project.git

cd project.git

git init --bare

--bare creates a storage space for your repository or a repository without a working directory.

In case you forget to change directory to project directory when running the git init --bare command, you can undo the command by running rm -rf branches config description HEAD hooks info objects refs to remove the git folder created. A normal git init creates a hidden .git folder but when you perform a --bare init, several folders are created at the current folder.

Copy User Public SSH Key to Clipboard

From your local computer, copy and add public keys for any users you would like to access the private git server.

  • If using a Mac, run

    pbcopy < ~/.ssh/

    The above command will copy the contents of the public SSH key file to the clipboard. Remember to replace ~/.ssh/ with your user’s SSH public key

  • You can also open your SSH public key with your text editor, select all the contents of the file and copy the contents to the clipboard

Append SSH Key to Git Server Authorized Keys

On your Git server, open ~/.ssh/authorized_keys with your favorite text editor.

vi ~/.ssh/authorized_keys

Append the contents of the key file we copied in the previous step at the end of the file.

Save the file and and close the text editor.

Managing Multiple SSH keys on Your Local Computer

In situations where you have multiple SSH keys on your local computer, then you can specify the configuration file to use on the command line.

GIT_SSH_COMMAND='ssh -i ~/.ssh/kagundajm-rsa' git push website

Using this approach would require specifying the key every time you are executing a Git push command.

A better alternative would be to create a custom SSH configuration file. Using a configuration file, we will assign an alias name to our remote connection and use this name when accessing these remote computers. This is the approach we will adopt.

Using your preferred Editor, open your custom configuration file

vim ~/.ssh/config

Append the following to the configuration file:

Host website
    User git
    IdentityFile ~/.ssh/kagundajm_droplet_rsa
    IdentitiesOnly yes

Note that indentation is not required but is used here to make it easier to read the available options within the file. Also you can assign Host any name you prefer; in this instance our Host is named web.

Save the changes and close the text editor.

By default, the SSH configuration file does not exist. If a new file was created, make sure to grant read/write permissions to the owner no permissions to the group and anyone else (others).

chmod 600 ~/.ssh/config

Now the git user can use SSH connections to ssh into the server, push, pull or even clone from the repository using commands like the following:

    ssh website

    git clone website:project.git

    git push website

Add Remote Git Repository to Local Git Config

On your local computer, you may be in one of two scenarios. Either you have an existing git repository or you are creating a new repository. In this post, we will be using website as the name of our remote directory but you can use any name you prefer.

  • if you already have an existing local repository.

    • add the remote git project directory to the local .git/config.

      git remote add website website:project.git
    • Push the contents of the local repository to the remote one.

      git push website +master:refs/heads/master

      website is the name of the remote repository we want to add

      master:refs/heads/master is a refspec that can be used for fetching.

      The format for the refspec is +<src>:<dest> with the + being optional.

  • if it is a new git repository you are setting up, then use run the following commands from the Terminal.

      git init
      git add .
      git commit -m 'initial commit'
      git remote add website website:project.git
      git push website master

Any future changes you make locally can now be uploaded to the remote repository simply by running

git push website

Git Server Side Hook to Deploy to Web Server on Git Push

Git hooks are custom scripts that Git executes when certain actions occur. There are client side and server side hooks. These hooks are stored in .git/hooks folder. In automatically updating our web server, we will use post-receive server side hook.

Make sure you are using the user you used to create git user

Create your project’s folder on the web server

sudo mkdir /var/www/project01

Change group ownership of web folder to git:www-data.

sudo chown -R git:www-data /var/www/project01

Grant write permissions on the folder to the new owner and group

sudo chmod -R ug+rwx /var/www/project01/

Make all new files and subdirectories created within project01 inherit the folder’s group id (www-data) of the directory rather than the group ID of the user who created the file/directory.

sudo chmod g+s /var/www/project01

Now that we have setup the project folder on the web server, switch back to git user

sudo su git

Move to root of your git project

cd ~/project.git

Create a post-receive hook that will checkout your latest push to the web server

vi hooks/post-receive

Update the hooks/post-receive file with the following:


GIT_WORK_TREE=/var/www/ git checkout -f

Save the changes and close the text editor.

Make hooks/post-receive file executable

chmod +x hooks/post-receive

A successful git push will now trigger the post-receive hook which will copy the latest contents of the repository to your web server.

Prevent Git Users Interactive Login Into the Server

Using SSH to login to a server also provides an interactive shell access to the remote Git users. To restrict the users to only Git-related activities for managing the repositories, we need to replace the shells assigned to git-shell which is a more restrictive shell.

List the available shells to determine whether git-shell is already included among the shells.

cat /etc/shells

If git-shell is not listed, find out where it is located.

which git-shell

Take note of the displayed git-shell path

Open /etc/shells with your text Editor

sudo vim /etc/shells

Append the path to /etc/shells

Save the changes and close the text editor.

Edit the shell for Git users to git-shell

sudo chsh git -s $(which git-shell)

Note you can always change back to the default bash shell for the Git user by running

sudo chsh git -s $(which bash)

Now all Git users will only use SSH connections to push and pull Git repositories.


  1. HOWTO setup a private git server on Ubuntu 18.04
  2. 4.4 Git on the Server - Setting Up the Server
  3. A git Primer
  4. Using Git to manage a web site
  5. How To Set Up Automatic Deployment with Git with a VPS