Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What is the best way to set up users and permissions for a production web server that uses git to deploy to the server?


Running Ubuntu 12.04, I have apache serving files under /var/www as www-data. I also had a bare git repo under the root users directory that would checkout to /var/www/ in the post-receive hook.

This worked fine, but considering it's a production server, I wanted to button up some security and remove the repo from the root user. So I created a git user and set up the repo under /home/git. But now I have permissions issues over the fact that one user owns the repo while another user owns the web root.

I've read many forums and tutorials online. Most seem to just use the root user, others seem to have worse security issues (such as giving www-data read permissions over the repo). I'm looking for insights from real-world experience because there are many ways this could be done.

As a note, the post-receive hook does more than checkout. It also performs some build processes such as running Composer and some other php scripts that can take several minutes.

I have tried several solutions:

I tried adding the git user to the www-data group, then chowning the web root back to www-data at the end of the hook. This has two issues. First, I have to modify the sudoers file, and the results I get from that are hit and miss. Second, during those several minutes while the hook is running, the checked-out files are owned by git, not www-data, so users on the site might get read errors.

I tried putting the contents of the post-receive in another file, and executing it with sudo. Again, this requires editing the sudoers files, so that the git user can sudo without a password.

Or it could be that leaving the repo under the root user is the lesser evil and I'm doing all this for nothing.

Is there a better solution that I haven't tried?

share|improve this question
up vote 4 down vote accepted

Create a new group, and add the git and www-data user into it. Then setup your git bare repository to always use the group you created as the gid for the repository files. With a new bare respiratory you do this with like this git init --shared=group. (Ref) This will permit the www-data account to read the repository.

Update your sudoers to permit the git account to run commands as www-data without a password.

# file: /etc/sudoers.d/gitpush
# permissions should be 0440
# git user is allowed to basically do anything as the www-data user
git ALL=(www-data) NOPASSWD: ALL

Then simply have your post-receive script sudo -u www-data for all the commands needed to perform the check/fixes.

share|improve this answer

I think there's a better way to handle this scenario.

First, I would switch from plain git to something with some sort of role based access control (RBAC), like gitolite.

I would also recommend to read this article describing a workflow very similar to the one you need.

To implement a solution for your requirements, the steps would be:

  1. grant RBAC using RSA keys using gitolite
  2. configure and use the hooks described in the article linked above to ensure correctness regarding owner, group and permissions.

The advantages are many, in my opinion:

  1. you don't need to give direct access to the files to anybody
  2. you can trigger anything from the post-update hook scripts
  3. every interaction with the published content occurs through the gitrepository, so auditing becomes a a simple task (git log and git blame)
  4. you don't need to play with ACLs or mixing group permissions (DAC)
  5. you can use mandatory access control (MAC) security transparently
share|improve this answer

On a standard mod_php /var/www/ could be owned by a git user, and any files/folder needed to be writable by php, would need to be owned by www-data ( or have 666/777 permissions). In this case one virtualhost could write the other virtualhost files.

Or : If you are running mod_php, you could add for example mod_ruid2 to Apache, then run each virtualhost with his own uid. Which would be the git user in this case. Or php-fpm if you prefer fastcgi like setup and each virtualhost having own php-fpm pool. This way each virtualhost could write own files, but not files from other virtualhosts.

Depends, which way you prefer.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.