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.
First thing is to log into the server and install Git.
For an .deb based system run.
$ sudo apt update $ sudo apt install git
For an .rpm based system run.
$ sudo yum install git OR $ sudo dnf install git
The next step is to create a git user.
$ sudo useradd -r -m -U -s /bin/bash git
creates a system user
creates a home directory
create a group name the same as the username.
Set the default shell for the user.
You should see the git home directory created under /home.
$ ls -lF /home/ total 8 drwxr-xr-x 2 git git 4096 Jan 29 20:09 git/
Set a password for the git user.
$ sudo passwd git
Switch accounts to become the git user.
$ su - git
Create a .ssh directory in the git user’s home folder.
$ mkdir /home/git/.ssh
You will see that the default permissions are 0755 (drwxr-xr-x).
$ 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.
$ sudo chmod 0700 /home/git/.ssh
Verifying the permissions are set correctly by running “ls -ld”.
$ 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 (recommended). This reminds us that the directory is a repository and not a regular directory.
$ git init --bare my_project.git
Nice! Let’s work on the client computer.
At this time we will create SSH keys with this command.
$ ssh-keygen -t rsa -b 4096 -C “my_email” -f ~/.ssh/id_rsa
Type of key (rsa or dsa). Use rsa.
Specifies the number of bits in the key to create. Use 4096.
Add a comment.
Specify the path to the rsa file. It is common to name it
Upon running the command you will see output similar to what is below. Set a password when prompted.
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-------).
$ 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. Change the IP address to the IP address of your server.
$ ssh-copy-id -i ~/.ssh/id_rsa.pub email@example.com
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.
$ ssh firstname.lastname@example.org email@example.com password: Last login: Fri Jan 29 20:35:46 2021 from 192.168.12.100 firstname.lastname@example.org:~ $
Type exit to disconnect from the server.
email@example.com:~ $ 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/.
$ mkdir my_project/ $ cd my_project/
Add a few of the standard git files.
$ touch readme.md .gitignore LICENSE
Add some content to the readme.md.
$ echo ‘# My First Project!’ >> readme.md
Add all the files to the git staging area so they can be committed.
$ git add --all
Commit the files to git. The -m allows you to create a short commit message without opening an editor.
$ 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>
can be whatever label you want. I set my “remote_name” to “local” since I have a local server. Change the IP address to the IP address of your server.
(master)my_project $ git remote add local firstname.lastname@example.org:my_project.git
Push the first commit to the server.
(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’.
(master)my_project $ git remote -v local email@example.com:my_project.git (fetch) local firstname.lastname@example.org: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 ” command to create a new repository without logging into the server. Run this command changing the IP address to your server’s IP address.
$ ssh email@example.com “git init --bare my_second_project.git”
Check that the directory was created on the server.
~ $ ssh firstname.lastname@example.org "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.
$ mkdir my_second_project/ $ cd my_second_project/ $ touch readme.md .gitignore LICENSE
Add some content to the readme.md.
$ echo ‘# My Second Project!’ >> readme.md $ git add --all $ git commit -m “First commit” $ git remote add local email@example.com:my_second_project.git $ git push local master firstname.lastname@example.org'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'.
Just to review, to create a new local repository you simply run the following commands.
$ ssh email@example.com “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 firstname.lastname@example.org:nodejs_app .git $ git push local master
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:
(master)my_project $ git remote add origin email@example.com/brandon-wallace:my_project.git
Look at the remote repositories available now.
(master)my_project $ git remote -v local firstname.lastname@example.org:my_project.git (fetch) local email@example.com:my_project.git (push) origin firstname.lastname@example.org/brandon-wallace:my_project.git (fetch) origin email@example.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
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.
$ 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.
$ 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.
$ 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.