Docker

Set Up a Git HTTP Server on Docker

Git HTTP server is very useful for people who want to work and collaborate on projects privately. In this article, I am going to show you how to set up an HTTP accessible Git server using Docker Compose.  So, let’s get started.

Requirements:

In order to follow this article, you must have Docker installed on your computer. LinuxHint has a lot of articles that you can follow to install Docker on your desired Linux distribution if you don’t have it installed already. So, be sure to check LinuxHint.com in case you’re having trouble installing Docker.

Installing Docker Compose:

You can download Docker Compose binary file very easily with the following command:

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/
docker-compose-$(uname -s)-$(uname -m)"
-o /usr/local/bin/docker-compose

NOTE: curl may not be installed on your Linux distribution. If that’s the case, you can install curl with the following command:

Ubuntu/Debian/Linux Mint:

$ sudo apt install curl -y

CentOS/RHEL/Fedora:

$ sudo dnf install curl -y

Once docker-compose binary file is downloaded, run the following command:

$ sudo chmod +x /usr/local/bin/docker-compose

Now, check whether docker-compose command is working as follows:

$ docker-compose version

It should print the version information as shown in the screenshot below.

Setting Up Docker Compose for the Project:

Now, create a project directory ~/docker/gitserver (let’s say) and a repos/ and etc/ directory inside the project directory for keeping the git repositories and some configuration files.

$ mkdir -p ~/docker/gitserver/{repos,etc}

Now, navigate to the project directory ~/docker/gitserver as follows:

$ cd ~/docker/gitserver

This is how the project tree should look like. Here, I have 2 files, git.conf and git-create-repo.sh in the etc/ directory. An empty repos/ directory for keeping all the Git repositories. A gitserver.Dockerfile for building a custom Git HTTP server Docker container and a docker-compose.yaml file.

The contents of the gitserver.Dockerfile:

FROM ubuntu:18.04
RUN apt update 2>/dev/null
RUN apt install -y git apache2 apache2-utils 2>/dev/null
RUN a2enmod env cgi alias rewrite
RUN mkdir /var/www/git
RUN chown -Rfv www-data:www-data /var/www/git
COPY ./etc/git.conf /etc/apache2/sites-available/git.conf
COPY ./etc/git-create-repo.sh /usr/bin/mkrepo
RUN chmod +x /usr/bin/mkrepo
RUN a2dissite 000-default.conf
RUN a2ensite git.conf
RUN git config --system http.receivepack true
RUN git config --system http.uploadpack true
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
CMD /usr/sbin/apache2ctl -D FOREGROUND
EXPOSE 80/tcp

The contents of etc/git.conf Apache configuration file:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
 
SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias / /usr/lib/git-core/git-http-backend/
 
Alias / /var/www/git
 
<Directory /usr/lib/git-core>
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride None
Require all granted
</Directory>
 
DocumentRoot /var/www/html
 
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

The contents of the etc/git-create-repo.sh Shell script:

#!/bin/bash
 
GIT_DIR="/var/www/git"
REPO_NAME=$1
 
mkdir -p "${GIT_DIR}/${REPO_NAME}.git"
cd "${GIT_DIR}/${REPO_NAME}.git"
 
git init --bare &> /dev/null
touch git-daemon-export-ok
cp hooks/post-update.sample hooks/post-update
git update-server-info
chown -Rf www-data:www-data "${GIT_DIR}/${REPO_NAME}.git"
echo "Git repository '${REPO_NAME}' created in ${GIT_DIR}/${REPO_NAME}.git"

Finally, the contents of the docker-compose.yaml file:

version: "3.7"
services:
  git-server:
    build:
      dockerfile: gitserver.Dockerfile
      context: .
    restart: always
    ports:
      - "8080:80"
    volumes:
      - ./repos:/var/www/git

Building Git HTTP Server Docker Image:

Now, to build the Git HTTP Server docker image, run the following command:

$ docker-compose build

It may take a while to build a custom Docker image.

At this point, the Docker image should be built.

Whenever you make any changes to any of the gitserver.Dockerfile, etc/git.conf, etc/git-create-repo.sh file, you must rebuild the Docker image using docker-compose build command.

Starting Git HTTP Server:

Now, to start the git-server service, run the following command:

$ docker-compose up -d

The git-server service should start in the background.

To see how the ports are mapped, run the following command:

$ docker-compose ps

As you can see, for the git-server service, the Docker host port 8080 is mapped to the container TCP port 80.

Creating New Git Repository on the Server:

To create a new Git repository test (let’s say) on the Git HTTP server container, run the following command:

$ docker-compose exec git-server mkrepo test

A new Git repository test should be created.

Finding the IP Address of Docker Host:

If you want to access the Git HTTP server from other computers on your network, you must know the IP address of your Docker host.

To find the IP address of your Docker host, run the following command:

$ ip

In my case, the IP address of my Docker host 192.168.20.160. It will be different for you. So, make sure to replace it with yours from now on.

Accessing Git Repositories from the Server:

You can access the Git repositories on the server using the URL http://<docker-host-IP>:8080/<reponame>.git

Here,

<docker-host-IP> is the IP address of your Docker Host.

<reponame> is the Git repository name in the Git HTTP server.

So, in my case, for the test repository, the URL should be http://192.168.20.160:8080/test.git

Now, you can clone the test Git repository from the server as follows:

$ git clone http://192.168.20.160:8080/test.git

As you can see, the repository is cloned successfully. But it’s currently empty.

A new directory test/ should be created.

$ ls

Navigate to the test/ directory.

$ cd test/

Now, make some changes and commit it.

$ echo "welcome to git-server" > message.txt
$ git add -A
$ git commit -m 'initial commit'
$ git log --oneline

Now, push the changes to the server as follows:

$ git push origin master

As you can see, the commits are sent to the Git HTTP server successfully.

Now, someone else can clone the test Git repository as well.

$ git clone http://192.168.20.160:8080/test.git

Navigate to the test/ directory.

$ cd test/

And find the changes there.

Stopping the Git HTTP Server:

To stop the git-server service, run the following command:

$ docker-compose down

The git-server service should be stopped.

So, that’s how you set up a Git HTTP server using Docker. Thanks for reading this article.

About the author

Shahriar Shovon

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of the demanding public engineering universities of Bangladesh.