January 3, 2016

513 words 3 mins read

You appear to have cloned an empty repository on GitLab

A great way to manage your private projects at your company is by having your own Github like site, this is what Gitlab is all about. I’ve been using the project for about two years now and it has been great so far, during all of this time I’ve used jenkins to automate builds for some projects which is great, but now I’m trying to experiment with Gitlab CI since it’s bundled into Gitlab itself, I think it’s worth taking the time to try it.

The easiest way to install Gitlab is via the omnibus packages, I did perform the installation that way but I have a custom setup since my Gitlab site is served via Vesta CP a simple appliance for managing web sites with Nginx and Apache.

However when I set up a Gitlab CI Runner I keep having this error while starting the build of the project:

Cloning repository… Cloning into ‘builds_896c2f68/0_dms/project’… warning: You appear to have cloned an empty repository. Checking out 4b50f510 as dev… fatal: reference is not a tree: 5b50f5157f357f4c006chcif0e36085bad300184

I haven’t run into this problem before because I always use the SSH URL instead of the HTTP URL of the repo, but this is not the way Gitlab CI works. gitlab-git-http-server is the application in charge for giving us a repo via its HTTP URL, now it’s been renamed to gitlab-workhorse. This separation of concerns is necessary to free up the unicorn server of huge performing tasks such as the cloning process, that way unicorn only handles the interaction within the Gitlab site, while heavier tasks are run with gitlab-workhorse. My problem was that due to my custom setup I forgot to setup the reversed proxy to Gitlab workhorse which in fact handles cloning repositories via the HTTP URL.

I’ve installed Gitlab via omnibus packages so I already have gitlab workhorse installed, but if you don’t just install install gitlab-workhorse.

If you’re unsure whether you have Gitlab Workhorse installed just search for listening connections from gitlab-workhorse:

$ ss -xl | grep gitlab

You should see the matching socket paths for gitlab:

u_str LISTEN 0 128 var_opt_gitlab_gitlab-workhorse_socket 6105053 * 0 u_str LISTEN 0 128 /var_opt_gitlab_redis_redis.socket 6106250 * 0 u_str LISTEN 0 128 /var_opt_gitlab_postgresql.s.PGSQL.5432 6106238 * 0 u_str LISTEN 0 128 /var_opt_gitlab_gitlab-rails_sockets_gitlab.socket 6107233 * 0

As you can see there’s a socket listening for gitlab-workhorse now in my custom Nginx config file I just need to set up a reversed proxy to that socket.

# This goes inside the "server" block
location ~* \.(git) {
    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;

    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host              $http_host;
    proxy_set_header   X-Real-IP         $remote_addr;
    proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header   X-Frame-Options   SAMEORIGIN;
    proxy_pass http://gitlab-workhorse;

Then define the gitlab-workhorse upstream (this needs to be outside the server block):

upstream gitlab-workhorse {
    server unix:/var/opt/gitlab/gitlab-workhorse/socket;  # Path to the socket file

That’s it! Reload nginx and now all request for URLs matching *.git will be passed to the gitlab-workhorse via a UNIX socket (you can also setup a TCP address if you want) and now your HTTP repo URL will be working just fine.