Setting Up an HTTP Git Server with Nginx on Ubuntu 20.04: A Step-by-Step Guide

Git is a robust, free, and open-source versioning system created by Linus Torvalds, widely used by developers across the globe. While GitHub offers free code hosting services, it does not support private hosting under its free plan. In such scenarios, setting up your own code hosting server using a Git HTTP server becomes viable, providing you with complete control over your server.

In this tutorial, we will explore how to install and configure a Git HTTP server with Nginx on Ubuntu 20.04.

Prerequisites

  • A server running Ubuntu 20.04.
  • A valid domain name pointed to your server’s IP.
  • Your server should have a root password configured.

Getting Started

Before diving into the installation process, it’s advisable to update your server packages to their latest versions. Execute the following command to update them:

apt-get update -y

Once updated, you’re good to proceed to the next step.

Install Nginx and Git

To start, you’ll need to install Nginx, Git, and other necessary packages on your system. Use the following command to install these:

apt-get install nginx git fcgiwrap apache2-utils unzip -y

With all the packages installed, you can move forward to creating your Git repository.

Create a Git Repository

Next, create a Git repository within the Nginx web root directory. Begin by creating a directory named “git” with the following command:

mkdir /var/www/html/git

Transition into the “git” directory and create a new directory for your Git repository:

cd /var/www/html/git
mkdir gituser.git

Change into this new directory and set up the Git repository using the command:

git --bare init

Update the Git Server settings:

git update-server-info

Adjust the ownership and permissions of the git directory with the following commands:

chown -R www-data:www-data /var/www/html/git
chmod -R 755 /var/www/html/git

Now, create a new gituser for authentication:

htpasswd -c /var/www/html/git/htpasswd gituser

You will be prompted to set a password as shown below:

New password: 
Re-type new password: 
Adding password for user gituser

Verify your password by using the command:

cat /var/www/html/git/htpasswd

The output should display:

gituser:$apr1$iPKZDbFB$ziRRbGXzVMMHaPYOtL05m/

Configure Nginx for Git

Configure Nginx to serve the Git repository by creating a new virtual host configuration file for Git:

nano /etc/nginx/conf.d/git.conf

Add the following lines:

server {
        listen 80;

        root /var/www/html/git;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name git.example.com;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

location ~ (/.*) {
    client_max_body_size 0; 
    auth_basic "Git Login"; 
    auth_basic_user_file "/var/www/html/git/htpasswd";
    include /etc/nginx/fastcgi_params; 
    fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; 
    fastcgi_param GIT_HTTP_EXPORT_ALL "";
    fastcgi_param GIT_PROJECT_ROOT /var/www/html/git;
    fastcgi_param REMOTE_USER $remote_user;
    fastcgi_param PATH_INFO $1; 
    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
}
}

Save and close the file. Verify Nginx for any syntax errors by executing:

nginx -t

The output should confirm the configuration is correct:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Restart the Nginx service to apply the changes:

systemctl restart nginx

You can also verify the running status of the Nginx service:

systemctl status nginx

The output should indicate that Nginx is up and running:

? nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2020-11-17 07:43:46 UTC; 4s ago
       Docs: man:nginx(8)
    Process: 3240 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 3256 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 3257 (nginx)
      Tasks: 3 (limit: 4691)
     Memory: 3.5M
     CGroup: /system.slice/nginx.service
             ??3257 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             ??3258 nginx: worker process
             ??3259 nginx: worker process

Nov 17 07:43:46 ubuntu2004 systemd[1]: Starting A high performance web server and a reverse proxy server...
Nov 17 07:43:46 ubuntu2004 systemd[1]: Started A high performance web server and a reverse proxy server.

Test HTTP Git Server

With the Git server setup, it’s time to test its functionality:

On a client machine, install Git with:

apt-get install git -y

Create a directory named “myapp”:

mkdir myapp

Navigate to the new directory and initialize Git:

cd myapp
git init

Add your remote Git repository:

git remote add origin http://gituser@git.example.com/gituser.git

Create “app1” and “app2” directories and files within them:

mkdir app1 app2
echo "This is my first application" > app1/app1
echo "This is my first application" > app2/app2

Add all directories and files to the repository:

git add .

Commit the changes:

git commit -a -m "Add files and directories"

The output should confirm the commit:

[master (root-commit) 4e90372] Add files and directories
 2 files changed, 2 insertions(+)
 create mode 100644 app1/app1
 create mode 100644 app2/app2

Push these changes to the remote Git server:

git push origin master

Enter the password when prompted. The successful push will result in:

Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 354 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To http://gituser@git.example.com/gituser.git
 * [new branch]      master -> master

To clone this repository to your local system, use the following command:

git clone http://gituser@git.example.com/gituser.git

You should see output indicating a successful clone:

Cloning into 'gituser'...
Password for 'http://gituser@git.example.com': 
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
Checking connectivity... done.

Conclusion

Congratulations! You have successfully installed and set up a Git HTTP server on an Ubuntu 20.04 server. Your Git server is now ready to be integrated into your development environment and accessed locally within your LAN.

Frequently Asked Questions (FAQ)

  • What is the primary advantage of using a self-hosted Git server?Hosting your own Git server gives you complete control over your codebase, including privacy, security, and the ability to customize the server’s environment to meet your needs.
  • Can this Git server setup be accessed from outside the LAN?Yes, by configuring the server with a valid domain and setting up appropriate firewall and network rules, the server can be accessed remotely.
  • Is it possible to add more users to the Git server?Absolutely! You can add more users by creating additional entries in the `htpasswd` file with different usernames and passwords.
  • How can I secure my Git server further?Consider implementing HTTPS for encrypted communication and configuring firewall rules to restrict access.
  • Can I switch from HTTP to SSH for accessing the Git server?Yes, switching to SSH offers enhanced security and is recommended for production environments. This setup would require additional configuration for SSH access.