How to setup your own git repo with HTTP access [DEBIAN]

Find an article
Apr 25
Published by in · Leave your thoughts
( words)
Warning! There was an error loading some of the images for this post.

Sometimes you find yourself thinking: “I don’t really want to host this code on someone else’s servers.” Especially if you’re particularly fond of your own privacy, and like the flexibility and control of running your own services. One day a project came up that I didn’t really want to host on GitHub, likewise I had ran out of private repositories anyway. The process for configuring your own git server seemed simple so here’s how I did it:

1) Install git:

aptitude install git

2) Configure a directory where you would like your git repositories to be stored.

mkdir /var/git

3) Optional: Add a new group allowing you to control who has physical access to the git repositories. Here I add both my personal account and the account running the web server (we’ll get to this later).

groupadd git
usermod -a -G git www-data

Set the directory to be owned by the new git user group.

chown :git /var/git

Set the group bit to ensure all new files created in this directory use the git group.

chmod 2775 /var/git

4) Create the git repository! This creates a bare git repository (without the extra heterogeneity) and configures it to allow group access (the git user we just created).

cd /var/git
mkdir my-repo-name.git
cd miami-nice.git
git init --bare --shared=group

That’s it! The repository is now created and ready for use, however, I wanted to enable HTTP access to the repository so that I can both view it in a pretty interface and push to the repository without having to create a new SSH user for each developer.

5) Configure HTTP access in git

git config --file config http.receivepack true
cd hooks
mv post-update.sample post-update

6) Create accounts for each developer.

aptitude install apache2-utils
htpasswd -m -c /etc/nginx/git-internal.htpasswd developer-username
chmod 640 /etc/nginx/git-internal.htpasswd
chown :www-data /etc/nginx/git-internal.htpasswd

7) Configure the web server to allow HTTP access to the git repositories. Now, because I didn’t want to use a sub-domain like many tutorials suggest I had to improvise and create what I can only describe as a fake directory so any requests to http://mydomain.com/git/ will require you to have a authenticate and also allow for HTTP access to any git repositories.

location ~ ^/git {
    dav_methods  PUT DELETE MKCOL COPY MOVE;
    create_full_put_path   on;
    auth_basic             "Git Repositories";
    auth_basic_user_file   /etc/nginx/git-internal.htpasswd;
    dav_access             group:rw  all:rw;

    # static repo files for cloning over https
    location ~ ^.*\.git/objects/([0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+.(pack|idx))$ {
        alias /var/git;
    }

    # requests that need to go to git-http-backend
    location ~ ^/git(/.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|receive)-pack))$ {
        root /var;

        fastcgi_pass unix:/var/run/fcgiwrap.socket;
        fastcgi_param SCRIPT_FILENAME   /usr/lib/git-core/git-http-backend;
        fastcgi_param PATH_INFO         $1;
        fastcgi_param GIT_HTTP_EXPORT_ALL "";
        fastcgi_param GIT_PROJECT_ROOT  /var/git;
        fastcgi_param REMOTE_USER $remote_user;
        include fastcgi_params;
    }
}

 

Web Interface
Originally I tried to configure gitweb, which is the web interface that comes shipped in the git package. After numerous configuration attempts this didn’t seem to be very easy to configure the way I required. A later found a much prettier and open source solution known as gitlist.org.

1) Download and extract the latest version of GitList

wget https://s3.amazonaws.com/gitlist/gitlist-0.4.0.tar.gz
tar -zvxf gitlist-0.4.0.tar.gz - C /var/www/git

2) Configure gitlist

cd /var/www/git/
mkdir cache
chmod 777 cache
mv config.ini-example config.ini
vim config.ini

3) Update the web server. Notice how I used the same directory that I had earlier said was non-existent / fake? Here I edit the location ~ ^/git { block that I created earlier and add the following to it:

location ~ ^/git {
    location ~* index.php$ {
        include /etc/nginx/php.conf;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            add_header Vary "Accept-Encoding";
            expires max;
            try_files $uri @gitlist;
            tcp_nodelay off;
            tcp_nopush on;
    }
    try_files $uri @gitlist;
}
location @gitlist {
    rewrite ^/.*$ /git/index.php;
}

 

FAQ
When attempting to push code to the remote repository from my personal computer I get the following error:

error: RPC failed; result=22, HTTP code = 413

To fix this you need to edit the web server settings and ensure the make post size is of sufficient size, this worked for me:

client_max_body_size 20M; to /etc/nginx/nginx.conf

Leave a Reply

Your email address will not be published.