Set Up A GIT Server The Easy Way!
Tags: tutorial, git, linux
Published: 2021-02-07 02:35:19

# Introduction

In this tutorial I will show you step-by-step how to set up a local Git server. This is an easy and fun project that is great for a home server, a low-powered single board computer such as a Beaglebone Black or Raspberry Pi, or even a Virtual Private Server. All you need is Git installed on the server and an SSH key on the client computer.

The benefit to this is that are you will have your own private git server you control, where you can push, pull, and clone repositories from.

![client-server.png](https://i.postimg.cc/zvD6pnTQ/client-server.png)

Let’s begin…

# On the server

First thing is to log into the server and install Git.

For an .deb based system run.

```bash
$ sudo apt update

$ sudo apt install git
```

For an .rpm based system run.

```bash
$ sudo yum install git

OR

$ sudo dnf install git
```

The next step is to create a git user.

```bash
$ sudo useradd -r -m -U -s /bin/bash git
```

`-r`

creates a system user

`-m `

creates a home directory

`-U`

create a group name the same as the username.

`-s /path/to/shell`

Set the default shell for the user.

You should see the git user's home directory created under /home.

```bash
$ ls -lF /home/
total 8
drwxr-xr-x  2 git git 4096 Jan 29 20:09 git/

```

Set a password for the git user.

```bash
$ sudo passwd git
```

Switch accounts to become the git user.

```bash
$ su - git
```

Create a .ssh directory in the git user’s home folder.

```bash
$ mkdir /home/git/.ssh
```

You will see that the default permissions are 0755 (drwxr-xr-x).

```bash
$ ls -ld /home/git/.ssh
drwxr-xr-x 2 git git 4096 Jan 29 20:25 /home/git/.ssh
```

We need to set the permissions on the .ssh directory to 0700 so that SSH will function correctly. We will set the directory permission to 0700 (drwx------) with this command.

```bash
$ sudo chmod 0700 /home/git/.ssh
```

Verifying the permissions are set correctly by running “ls -ld”.

```bash
$ ls -ld /home/git/.ssh
drwx------ 2 git git 4096 Jan 29 20:25 /home/git/.ssh
```

Let create our first repository on the server. By convention we append .git to the end of the directory name. This reminds us that the directory is a repository and not a regular directory.

```bash
$ git init --bare my_project.git
```

Nice! Let’s work on the client computer.

# On the client computer

At this time we will create SSH keys with this command.

```bash
$ ssh-keygen -t rsa -b 4096 -C “my_email” -f ~/.ssh/id_rsa
```

`-t <type>`

Type of key (rsa or dsa). Use rsa.

`-b <bits>`

Specifies the number of bits in the key to create. Use 4096.

`-C “comment”`

Add a comment.

`-f /path/to/key`

Specify the path to the rsa file. It is common to name it `id_rsa`.

Upon running the command you will see output similar to what is below. Set a password when prompted.

```bash
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): ************
Enter same passphrase again: ************
Your identification has been saved in .ssh/id_rsa.
Your public key has been saved in .ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Yg5D1kaIN9M6ln3sJlHzEggLoKpDYFkhXFR1ZOwP/sI my_email
The key's randomart image is:
+---[RSA 4096]----+
|oo+*+=ooo+       |
|..=.=+o *.       |
|oo .+*oo.+       |
|+  o=.o +o.      |
|.. .o.o+S.o      |
|o    =..o. .     |
|o     .o. .      |
| .       E .     |
|          .      |
+----[SHA256]-----+
```

You will see that two files have been created. `id_rsa` is the private key, `id_rsa.pub` is the public key. The permissions should be set to 0600 (-rw-------).

```bash
$ ls -la .ssh/
total 36
drwx------  2 bw bw 4096 Jan 29 20:43 .
drwxr-xr-x 54 bw bw 4096 Jan 29 13:17 ..
-rw-------  1 bw bw 3414 Jan 29 20:43 id_rsa
-rw-------  1 bw bw  733 Jan 29 20:43 id_rsa.pub
```

The public key needs to be copied over to the git server. To do that use the `ssh-copy-id` command. Since my server’s IP address is `192.168.12.34` I run the command like this to copy the public key over to the server. Change the IP address to the IP address of your server.

```bash
$ ssh-copy-id -i ~/.ssh/id_rsa.pub git@192.168.12.34
```

`-i /path/to/public_key_file`

Specify the path to the public key.

After copying the public key over to the server test logging into the server via SSH. Change the IP address to the IP address of your server.

```bash
$ ssh git@192.168.12.34
git@192.168.12.34s password:

Last login: Fri Jan 29 20:35:46 2021 from 192.168.12.100
git@192.168.12.34:~ $
```

Type exit to disconnect from the server.

```bash
git@192.168.12.34:~ $ exit
```

Now we are ready to connect to the repository that we made earlier on the server. Create a directory of the same name as the repository minus the .git extension. On the server we have a directory called my_project.git so on the client computer you create a directory called my_project/.

```bash
$ mkdir my_project/

$ cd my_project/
```

Add a few of the standard git files.

```bash
$ touch readme.md .gitignore LICENSE
```

Add some content to the readme.md.

```bash
$ echo ‘# My First Project!’ >> readme.md
```

Add all the files to the git staging area so they can be committed.

```bash
$ git add --all
```

Commit the files to git. The `-m` flag allows you to create a short commit message without opening an editor.

```bash
$ git commit -m “First commit”
```

We need to specify the git server we will be using.
This command will specify a remote git server repository where commits will be stored. The syntax is

`$ git remote add <remote_name> git@<server_ip>:<git_repo>`

 <remote_name> can be whatever label you want. The default `<remote_name>` you will often see is usually `origin`. I set my “remote_name” to “local” since I have a local server. Change the IP address to the IP address of your server.

```bash
(master)my_project $ git remote add local  git@192.168.12.34:my_project.git
```

Push the first commit to the server.

```bash
(master)my_project $ git push local master
```

Check your remote servers like this. Right now only one repository is  
set up which is called ‘local’.

```bash
(master)my_project $ git remote -v
local	git@192.168.12.34:my_project.git (fetch)
local	git@192.168.12.34:my_project.git (push)
```

Remember that I said we were going to do this the easy way?
Since we have finished the initial set up on the server we can create a new repository from the client computer using SSH. No need to log into the server to create the repository. Here is the workflow for creating a new repository on your Git server.

To run a command on a remote server just append the command you wish to run after the SSH command. This will allow you to run the “git init --bare <repo_name>” command to create a new repository without logging into the server. Run this command changing the IP address to your server’s IP address.

```bash
$ ssh git@192.168.12.34 “git init --bare my_second_project.git”
```

Check that the directory was created on the server.

```bash
~ $ ssh git@192.168.12.34 "ls -lF"
total 8
drwxr-xr-x 7 git git 4096 Feb  5 17:47 my_project.git/
drwxr-xr-x 7 git git 4096 Feb  6 21:48 my_second_project.git/
```


On the client computer create a directory with the same name as the git repository you created on the server minus the .git extension.

On the server we already have a my_second_project.git directory, so create the my_second_project/ directory on the client computer.

```bash
$ mkdir my_second_project/

$ cd my_second_project/

$ touch readme.md .gitignore LICENSE
```

Add some content to the readme.md.

```bash
$ echo ‘# My Second Project!’ >> readme.md

$ git add --all

$ git commit -m “First commit”

$ git remote add local git@192.168.12.34:my_second_project.git

$ git push local master
git@192.168.12.34's password: ************
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 306 bytes | 306.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To 192.168.12.34:my_project.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'local'.
```

All done.

Just to review, to create a new local repository you simply run the following commands.

Full example:

```bash
$ ssh git@192.168.12.34 “git init --bare nodejs_app.git”
$ mkdir nodejs_app/
$ cd nodejs_app/
$ touch readme.md .gitignore LICENSE
$ echo ‘# My Nodejs App’ >> readme.md
$ git init
$ git add --all
$ git commit -m “First commit”
$ git remote add local git@192.168.12.34:nodejs_app.git
$ git push local master
```


# *NOTE:

If you wish to you could easily add a second connection to Github if you want to have that same repository online by running the ‘git remote add' command.
First create a new repository on Github with the same name (my_project) without any files such as the readme.md, .gitignore, or LICENSE because we already created them.

Second run the git remote add command. Here is an example:
```bash
(master)my_project $ git remote add origin git@github.com/brandon-wallace:my_project.git
```

Look at the remote repositories available now.

```bash
(master)my_project $ git remote -v
local	git@192.168.12.34:my_project.git (fetch)
local	git@192.168.12.34:my_project.git (push)
origin    git@github.com/brandon-wallace:my_project.git (fetch)
origin    git@github.com/brandon-wallace:my_project.git (push)
```

Now it shows that I have two git servers I can use, one is called `local` (my server) the other `origin` (Github).

# BONUS TIP!

After logging into your computer you can use ssh-agent to store the rsa key password so that you do not have to keep typing your SSH private key password every time you do a push to a repository. To store the SSH password run.

```bash
$ eval $(ssh-agent -s)

$ ssh-add /home/brandon/.ssh/id_rsa
Enter passphrase for /home/bw/.ssh/id_rsa: ***********
Identity added: /home/bw/.ssh/id_rsa (comment)
```

See that the environment variable is exists.

```bash
$ env | grep SSH

SSH_AUTH_SOCK=/tmp/ssh-08AsdfQWRTYE/agent.69007
SSH_AGENT_PID=69007
```

Now all your git push commands will not require you typing the password.

```bash
$ git push origin master
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 518 bytes | 518.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0)
To 192.168.12.34:my_project.git
   d06bb48..beee582  master -> master
```

Feel free to leave comments, questions, and suggestions.