Silmor . de
Site Links:
Impressum / Publisher

Managing a Web-Site with GIT

Stages of Site-Management

Many hackers will know the same stages of managing a web-site that I know: FTP, CMS, and VCS.

The first stage - "FTP" - is the one you are normally forced into by cheap service providers. In some rare instances you have a choice to use SFTP or SCP as a more secure protocol. You write your pages, upload them, find they do not work properly. Restart. Lose content. Do it again...

After a while you discover backups and maybe some form of version control. Life feels better, but not good yet. This is the stage that most non-geeks are stuck at.

Stage two is the use of a Content Management System (CMS) to write pages directly online. Good CMS'es allow you to test your content before you switch it on. At the start life feels great because you are freed from using HTML directly and you work directly in the framework of your web site. Later you start to worry about backups again and maybe you will bemoan the added strain of keeping the CMS up to date and of being unable to write web pages while offline (e.g. on the train commuting). Unfortunately there does not seem to be a good way of rescuing non-hackers from this stage.

Stage three is a fall-back to wanting to use version control software (VCS). With the twist that you want automatic updates. If you have some control over the server where you keep your version control software and your web-site this is feasible.

This short article describes how this very web-site is managed using GIT and Apache. My workflow for writing articles on this site is very simple: I have a complete copy of it on my laptop where I hack on the pages until I'm happy with the result - normally while I'm commuting (very offline: wireless connectivity is intermittent at best). Then (at home) I just push it to the server and don't worry about it any more.

Apache

The first important ingredient is an (almost) identical Apache setup on the server and on my laptop - I even use virtual hosts to manage multiple sites.

Using a modern Linux laptop this is rather simple to do: install Apache and all necessary modules (like PHP) locally - your distribution will normally have packages ready for this. You should secure it appropriately - you are doing experiments on it after all - either let it only listen on the localhost interface or block ports 80 and 443 in your firewall.

In order to have a clean site copy on the laptop it is usually the easiest way to add a virtual host just for this site. You need to tell Apache that you plan to use virtual host by adding a NameVirtualHost *:80 directive to it. For each site add a VirtualHost directive:

<VirtualHost mysite.copy:80>
   ServerName silmor.mine
   DocumentRoot /home/konrad/webdev/mysite
   <Directory /home/konrad/webdev/mysite>
       Order allow,deny
       allow from all
   </Directory>
</VirtualHost>

The document-root should be the path of the local copy of the web site. What you configure inside the Directory directive depends on your specific needs. The host-name listed next to VirtualHost and ServerName should not be identical to the actual name of the web site, but some localhost alias in the local /etc/hosts:

127.0.0.1 mylaptop.fqdn mylaptop mysite.copy localhost
#...

GIT

Initialize the document root as a GIT repository and copy the contents of the web site into it. If you are already using GIT, just use your local copy as document root. You can use the local Apache to test your modifications until you are happy with them.

Likewise on the server side the document root should be a GIT repository as well. You will push your changes to this repository once you are done editing and testing. Normally GIT would deny a push to a branch that is checked out, this needs to be allowed by setting the receive.denyCurrentBranch option - simply edit .git/config and add:

[receive]
    denyCurrentBranch = warn

Now GIT will allow you to push changes to this repository, but on the downside it will be inconsistent after the push. This can be fixed with a git reset, which can be executed automatically in a hook. Create .git/hooks/post-receive and put this into it:

#!/bin/sh

echo "Resetting head"

cd ..
unset GIT_DIR
git reset --hard

exit 0

The echo simply creates some text that will be shown in the output of git push. Since the script is executed inside the .git directory we need to go a level higher. The GIT_DIR variable needs to be unset to make GIT behave in its normal mode. The reset command obliterates all differences between the checked out files and the new revision - as a side effect all local edits are lost as well, so you either need to put all necessary modifications into GIT or into entirely unversioned files.

Depending on the content of your homepage you may want to place a .htaccess file in your .git directory on your server to prevent outsiders from copying all content and history of your homepage:

<Files *>
 Deny from all
</Files>

Webmaster: webmaster AT silmor DOT de