Introduction
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.
Prerequisites
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@23.45.90.11 -i ~/.ssh/kagundajm-droplet
- Using a domain name. You must configure your domain to point to DigitalOcean before you using the domain name.
ssh kagundajm@droplet.com -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 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
cd
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.
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/kagundajm-droplet.pub
The above command will copy the contents of the public SSH key file to the clipboard. Remember to replace ~/.ssh/kagundajm-droplet.pub
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
Back 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
Hostname droplet.com
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:
#!/bin/bash
GIT_WORK_TREE=/var/www/projects.droplet.com 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.
Top comments (0)