Setting up Smart HTTP for Git on Virtualmin

I set up Virtualmin with the default git repository module and was able to push and pull over normal HTTP with no problem. However, to my dismay I later found out that none of the git hooks (specifically the all-important post-receive) were executing as per this link.

From here the solution was to switch from ordinary HTTP to Smart HTTP using the git-http-backend executable, which could execute all the hooks and it supposedly much faster too.

  1. Copy the git-httpd-backend executable to the /home/domain/cgi-bin/directory and set the permissions to domain:domain. This is to avoid suexec problems.
    $ cp /usr/libexec/git-core/git-http-backend /home/domain/cgi-bin
    $ chown domain:domain /home/domain/cgi-bin/git-http-backend
  2. On /etc/httpd/conf/httpd.conf, add this to the VirtualHost for the domain:
    # Set the root directory where git repositories reside
    SetEnv GIT_PROJECT_ROOT /home/domain/public_html/git
    # By default, the git-http-backend allows push for authenticated
    # users and this directive tells the backend when a user is authenticated.
    # Export all repositories
    ScriptAlias /dev/ /home/domain/cgi-bin/git-http-backend/
    # Add this if it’s not already there
    DAV on
    AuthType Basic
    AuthUserFile /home/domain/etc/git.basic.passwd
    Require valid-user
    Satisfy All
    RedirectMatch ^/git(/+)$ /git/gitweb.cgi
    RewriteEngine off
    AddHandler cgi-script .cgi
  3. And then restart apache. Now all the repos are now available at*, e.g.,, and all the hooks will execute as expected.

Going forward, when you create a new repo via Virtualmin, you need to do these manual steps:

  1. Create an empty file /home/domain/public_html/git/reponame.git/git-daemon-export-ok.
  2. Create this as /home/domain/public_html/git/reponame.git/hooks/post-receive and make it executable by all, and owned by apache:domain:
    # An example hook script for the "post-receive" event.
    # The "post-receive" script is run after receive-pack has accepted a pack
    # and the repository has been updated. It is passed arguments in through
    # stdin in the form
    # For example:
    # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
    # see contrib/hooks/ for a sample, or uncomment the next line and
    # rename the file to "post-receive".
    # Echo to the client that you’re sending the mail now
    echo "Sending notification email..."
    . /usr/share/git-core/contrib/hooks/post-receive-email
    # Make sure to update the git repo info on the server for pulls by other clients
    git update-server-info
    echo "Updated server info."
  3. As per this link, set the permissions of the git directory as follows so as to avoid a write-permissions problem when pushing new files in commits (while making sure the gitweb.cgi script is only writable by the owner to avoid suexec errors that would appear in /etc/httpd/logs/suexec.log):
    $ cd /home/domain/public_html/git/
    $ chmod -R g+ws *
    $ chgrp -R domain *
    $ chmod -R g-w gitweb.cgi
    $ chmod -R g-s gitweb.cgi
  4. Update /home/domain/public_html/git/reponame.git/config to match the following:
    	repositoryformatversion = 0
    	filemode = true
    	bare = true
       mailinglist =,
       envelopesender =
       emailprefix = "[REPONAME] "

1 comment

Leave a comment

Your email address will not be published. Required fields are marked *