Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Serve git smart HTTP repositories with uWSGI and nginx

For some joint project of mine, I needed a way for them to access (clone, pull, push) the git repository that is hostet on my server without adding SSH accounts for them. With git 1.6.6 a feature called smart HTTP was introduced, which allows working with the repository via HTTP.

I set up the CGI script for smart HTTP git-http-backend using uWSGI and serve it (including basic authentication) via nginx. Let me show you how.

If you wonder how to set up uWSGI and nginx properly, please read my tutorial on that one. The following is completely comatible to the proposed setup. I assume you have both running and working, and will only show the configuration files for each.

My git repositories are subfolders of /srv/git. The following uWSGI config file wraps the CGI script of git's smart HTTP (you might have to adjust the location of the script):

[uwsgi]
plugins = cgi
chown-socket = http:http
processes = 1
threads = 4
cgi = /usr/lib/git-core/git-http-backend
socket = %drun/uwsgi.sock
pidfile = %drun/uwsgi.pid
logto = %dlog/uwsgi.log

It will create a socket in CONFIG_FILE_DIR/run which we will use to listen to. In my case, CONFIG_FILE_DIR is /srv/http/git-smart-http. Now, we need to tell nginx to listen to that socket:

server {
  listen       80;
  server_name  httpgit.YOURDOMAIN.tld;

  access_log CONFIG_FILE_DIR/log/access.log;
  error_log CONFIG_FILE_DIR/log/error.log;

  location ~ ^(.+)$ {
      include uwsgi_params;
      uwsgi_modifier1 9;
      uwsgi_pass unix:CONFIG_FILE_DIR/run/uwsgi.sock;
      uwsgi_param GIT_HTTP_EXPORT_ALL "";
      uwsgi_param GIT_PROJECT_ROOT    /srv/git;
      uwsgi_param PATH_INFO           $1;
      auth_basic "Restricted";
      auth_basic_user_file  YOURPASSWD;
  }

}

Don't forget to change YOURPASSWD and CONFIG_FILE_DIR to the folders/files on your computer. As you can see, we tell git to export ALL repositories with GIT_HTTP_EXPORT_ALL, set up some access control using a .passwd file and set up some logging. Of course, you can and should (!) easily add SSL support to the config. With these two bits of configuration loaded, you can already clone a repository with git clone http://httpgit.YOURDOMAIN.TLD/repo. In order to be able to push, you need to run the following line in your server's git repository:

# git config --file config http.receivepack true

Well, have fun gitting! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment