We have apache server which serves a site from public_html/site/ We would like to have a mercurial repo in the same dir, so that we could push our changes directly to the server.

So far I setup a hgweb.wsgi script and I can push and pull from the repo without any problems.

Problems start when I want to add an authentication. Both read and write access to the repo should be forbidden for unauthorized users. Mercurial help mentions using HTTP auth, well, I can create .htaccess with .htpasswd, and place them in public_html/site/, but that would make the website not accessible.

Please help.

Update (solution): Perhaps the virtual hosts solution could work too, but I found a simpler one. You do not have to place authentication in the site dir, you have to place it where your hgweb script resides. Then just forbid access to .hg dir in the site dir and that's it!

Now pulling and pushing works through hgweb script only, with authentication.

  • 1
    The only solution that I can think of is using a separate dir as repo and a separate dir as site dir. When we push to the repo, a hook could copy changes to the site dir automatically. But is there a way to have repo and site dir in the same folder? – Jevgenij Evll Jan 11 '13 at 10:02

You could setup two vhosts on the server that point to the same document root. One vhost serves the website and the other one the mercurial repository with hgweb.wscgi. That way you can setup authentication inside the second vhost config.

<VirtualHost *:80>
  ServerName www.example.com
  ServerAlias example.com 
  DocumentRoot /www/domain/public_html/site/

<VirtualHost *:80>
  ServerName repo.example.com
  DocumentRoot /www/domain/public_html/site/

 # auth setup

If you prefer to use .htaccess then you could also use different names for the htaccess files by using the AccessFileName directive in the vhost config.
For example:

AccessFileName .acl

The way I usually do this is to use SSH instead of hgweb for push and pull. The scheme works as well if you push to site directory directly, however I recommend against that for a couple of reasons. First, pushing to a nonbare repository would still need a checkout anyway (this can be easily fixed with an incoming hook), second if you mess up deployment, it's much easier to fix if your site directory is separate from the repository directory, additionally having separate directories allows you to push to the shared repository without deploying (for example when you need to move codes that are not ready for live from one development machine to another development machine).

So the scheme works like this:

  1. Server
    1. "bare" repository directory: shared repository
    2. "live" site directory: hg pull /path/to/bare (create a [paths] entry for this in hgrc)
    3. script/alias to pull from bare to live and do other deployment tasks
    4. ~/.ssh/authorized_keys contains public key for ssh access
  2. Local
    1. "local" development directory: hg push ssh://username@example.com/path/to/bare (create a [paths] entry for this in hgrc)
    2. ~/.ssh/rsa_id is used for secure, passwordless push

Using SSH would also be more secure than using hgweb since the Apache process should not be able to write to the "live" site directory nor "bare" repository directory. Pushing through SSH means only the SSH user needs write access to those directories.

Without a bare repository, it looks slightly simpler like this:

  1. Server
    1. "live" site directory
    2. ~/.ssh/authorized_keys contains public key for ssh access
  2. Local
    1. "local" development directory: hg push ssh://username@example.com/path/to/live (create a [paths] entry for this in hgrc)
    2. ~/.ssh/rsa_id is used for secure, passwordless push

but you lose the advantages I mentioned above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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