Redmine, Mercurial through Lighttpd/FastCGI on Fedora 13

This article provides steps to follow to get a Mercurial server with the Redmine project management tool on a Fedora 13 host. The final setup will provide multiple Mercurial repositories published through HTTP, with the push back to the repository enable with digest HTTP authentication. This documentation could work for other Fedora-based distribution like Red Hat Linux or CentOS.

Choice has been made to use Lighttpd as HTTP server and FastCGI, a commonly advised alternative to the CGI system. The database server chosen for Mercurial is MySQL, though PostgreSQL can be used (see official install procedure URL at the bottom)

Following versions will be used :

  • Redmine 0.9.6 from sources since no package is available from Fedora repositories
  • Mercurial 1.6.3 (as provided by Fedora 13)
  • Lighttpd 1.4.26 (as provided by Fedora 13)
  • MySQL 5.1.42 (as provided by Fedora 13)

I assume that commands described below are executed as root.

  • Disable the firewall  and SELinux

Fedora 13 provides an enabled firewall by default, preventing any common network access to the host, like SSH or HTTP and the default SELinux enforcement method prevents Lighttpd from some needed filesystem accesses.

Those default behaviour are not what we want, so I decided to disable iptables and SELinux. These features are rarely needed on a repository server.

#Disable iptables
chkconfig iptables off
service iptables stop

#Disable SELinux permanently
sed -i "s/enforcing/disabled/" /etc/selinux/config
reboot
  • Install required packages from  Fedora repositories
yum install wget mercurial mysql-server lighttpd-fastcgi python-flup
yum install ruby-mysql rubygem-rake rubygem-rack rubygem-rails rubygem-RMagick
  • Install missing Ruby FastCGI bindings through the “gem” package manager
yum install gcc fcgi-devel ruby-devel
gem install fcgi
  • Enable the system services (MySQL, Lighttpd)
chkconfig lighttpd on
chkconfig mysqld on
service lighttpd start
service mysqld start
  • Install Redmine from sources, since Fedora doesn’t provide it
cd /var/www
wget http://rubyforge.org/frs/download.php/71530/redmine-0.9.6.tar.gz
tar xfz redmine-0.9.6.tar.gz
rm -f redmine-0.9.6.tar.gz
ln -s redmine-0.9.6 redmine
chown -R lighttpd:lighttpd redmine-0.9.6
mysql -e "create database redmine character set utf8;"
mysql -e "create user 'redmine'@'localhost' identified by 'my_password';"
mysql -e "grant all privileges on redmine.* to 'redmine'@'localhost';"
service mysqld restart
cat > /var/www/redmine/config/database.yml << EOF
production:
 adapter: mysql
 database: redmine
 host: localhost
 username: redmine
 password: my_password
 encoding: utf8
EOF

#Generate session store secret
RAISL_ENV=production rake config/initializers/session_store.rb

# Update the version requirement of Redmine to the version provided by Fedora
sed -i "s/1\.0\.1/1.1.0/" /var/www/redmine/vendor/rails/actionpack/lib/action_controller.rb

# Create the Redmine database and insert default configuration
RAILS_ENV=production rake db:migrate

# Select your language when the shell prompt it
RAILS_ENV=production rake redmine:load_default_data
  • Configure Lighttpd to serve Redmine through FastCGI
cd /var/www/redmine/public
mv dispatch.fcgi.example dispatch.fcgi
cat > /etc/lighttpd/conf.d/redmine.conf << EOF
# This ligne enables some modules needed by Redmine and/or Mercurial
server.modules += ( "mod_rewrite", "mod_alias", "mod_access",
"mod_auth", "mod_fastcgi", "mod_cgi" )

\$HTTP["url"] =~ "^/redmine" {
  alias.url = ( "/redmine" => "/var/www/redmine/public" )
  server.document-root = "/var/www/redmine/public/"
  server.indexfiles = ( "dispatch.fcgi" )
  server.error-handler-404 = "/redmine/dispatch.fcgi"
  fastcgi.server += (
    "dispatch.fcgi" => ( (
      "bin-path" => "/var/www/redmine/public/dispatch.fcgi",
      "socket" => "/var/run/lighttpd/redmine.socket",
      "min-procs" => 1,
      "max-procs" => 2,
      "bin-environment" => (
        "RAILS_ENV" => "production", "LANG" => "fr_FR.UTF8",
        "RAILS_RELATIVE_URL_ROOT" => "/redmine" ),
    ) )
  )
}
EOF
service lighttpd restart

Update the LANG environment variable following your locale, as the min-procs and max-procs FastCGI options following your needs.

Check that Lighttpd is running and serve Redmine by pointing your browser to http://ip-address/redmine. The default administrator account use “admin” as username and password.

  • Create Mercurial repositories and configure HTTP publishing
cd /var/lib
mkdir -p mercurial/repositories
chown -R lighttpd:lighttpd mercurial
cd mercurial/repositories
sudo -u lighttpd hg init my_project

cat > /etc/mercurial/hgweb.config << EOF
[collections]
/var/lib/mercurial/repositories = /var/lib/mercurial/repositories
EOF

cp /usr/share/doc/mercurial-1.6/hgweb.fcgi /var/www
chmod +x /var/www/hgweb.fcgi
sed -i "s/^config.*$/config=\"\/etc\/mercurial\/hgweb.config\"/" /var/www/hgweb.fcgi
  • Configure Lighttpd to serve Mercurial repositories
cat > /etc/lighttpd/conf.d/mercurial.conf << EOF
url.rewrite-once = ("^/hg$" => "/hg/" ) 

\$HTTP["url"] =~ "^/hg" {
 alias.url = ( "/hg" => "/var/www/hgweb.fcgi" )
 fastcgi.server += (
 "hgweb.fcgi" =>
 ((
 "bin-path" => "/var/www/hgweb.fcgi",
 "socket" => "/var/run/lighttpd/hgweb.socket",
 "min-procs" => 1,
 "max-procs" => 4,
 ))
 )
}
EOF

Check that Lighttpd is serving Mercurial repositories by pointing your browser to http://ip-address/hg. You should see the recently created “my_project” repository.

  • Finally, enable users to push back changes to repositories through digest authenticated HTTP
cd /root
wget http://redmine.lighttpd.net/attachments/download/844/htdigest.sh.txt -O htdigest.sh
chmod +x htdigest.sh

#Create users allowed to push back changes to the Mercurial repositories
./htdigest.sh -u username -p password -r hg -f /etc/mercurial/http-users
cat > /etc/mercurial/hgrc << EOF
[trusted]
users = *
groups = *

[web]
allow_push = username
push_ssl = false
EOF

# Enable the HTTP authentication for push commands
cat >> /etc/lighttpd/conf.d/mercurial.conf << EOF
\$HTTP["querystring"] =~ "cmd=unbundle" {
 auth.debug = 1,
 auth.backend = "htdigest",
 auth.backend.htdigest.userfile = "/etc/mercurial/http-users",
 auth.require = ( "" => (
 "method" => "digest",
 "realm" => "hg",
 "require" => "valid-user"
 ))
}
EOF

In order to commit and push changes, your current user will need a configuration file. The user defined in this file is textual only and doesn’t need to match the username used for the HTTP authentication.

cat > ~/.hgrc << EOF
[ui]
username = User <user@foo.fr>
verbose = True
EOF

You may now create a Redmine project and define its Mercurial source to /var/lib/mercurial/repositories/my_project. You ll need to create manually repositories with hg init before using it in Redmine.

Troubleshoot errors during the setup

  • Check that SELinux is disabled by executing /usr/sbin/selinuxenabled
  • Check that the firewall is disabled by execution /sbin/iptables -L
  • Check that redmine can be launched without Lighttpd to ensure the Redmine setup is complete and is accessible at the URL http://ip-address:3000/
sudo -u lighttpd ruby /var/www/redmine/script/server webrick -e production
  • Launch the Mercurial CGI in command line to ensure the publishing script is functionnal (as root and as “lighttpd” user). The output must contain the created repositories.
/var/www/hgweb.fcgi
sudo -u lighttpd /var/www/hgweb.fcgi
  • Try to clone the repository with and without HTTP authentication
hg clone http://localhost/hg/my_project
hg clone http://username:password@localhost/hg/my_project
  • Try to push back changes to the repository
cd my_project
touch a
hg add a
hg commit -m "first commit"
hg push
Posted in Uncategorized | 1 Comment