HowTo configure Redmine for advanced git integration » History » Version 11

Gregory Bartholomew, 2012-09-19 20:57
Added git-http-backend example with explination of REDIRECT_REMOTE_USER caveat

1 1 Felix Schäfer
h1. HowTo configure Redmine for advanced git integration
2 1 Felix Schäfer
3 3 Felix Schäfer
{{>TOC}}
4 3 Felix Schäfer
5 1 Felix Schäfer
h2. Scope
6 1 Felix Schäfer
7 1 Felix Schäfer
This HowTo explains how to serve git repositories on apache through the http-based "git-smart-http protocol":http://progit.org/2010/03/04/smart-http.html introduced in git 1.6.6. The git-smart-http offers various advantages over ssh or git-based access: you can use redmine access control as-is, no need for extra ssh keys or whatnot, you can secure it through SSL as needed, and there's generally less problems with firewalls and https/https ports than exist with ssh and git ports. git-smart-http also doesn't have some of the drawbacks of its "dumb" predecessor, as it doesn't require any complex DAV setup.
8 1 Felix Schäfer
9 7 Felix Schäfer
This HowTo is mainly written from memory and was conducted on a setup which was already serving [[Repositories_access_control_with_apache_mod_dav_svn_and_mod_perl|svn repositories integrated with redmine]], so it might be possible that I forgot some things or take them for granted. This is a wiki page, feel free to correct or amend anything you find lacking :-) You can also "drop me a line":/users/3866.
10 7 Felix Schäfer
11 7 Felix Schäfer
Another option to integrate grack with redmine is the "modified grack+redmine plugin":http://github.com/friflaj/redmine_grack or "any other grack modified for redmine":http://github.com/search?q=grack&type=Everything&repo=&langOverride=&start_value=1, though those ones lack documentation and I haven't tried them, so I can't say much about those.
12 1 Felix Schäfer
13 1 Felix Schäfer
h2. Prerequisites
14 1 Felix Schäfer
15 1 Felix Schäfer
* Apache with mod_perl (access control)
16 1 Felix Schäfer
* git (version at least 1.6.6)
17 1 Felix Schäfer
* A way to serve git-smart-http
18 1 Felix Schäfer
** mod_cgi (or mod_cgid) if you want to use the stock "git-http-backend":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html
19 10 Hallison Vasconcelos Batista
** a rack server if you want to use "grack":http://github.com/schacon/grack (basically a rack wrapper around the right git commands) or
20 10 Hallison Vasconcelos Batista
"git-webby":http://git.io/BU7twg (another implementation based on grack but written in Sinatra).
21 1 Felix Schäfer
22 6 Felix Schäfer
You should already have a rack server to run redmine, and that's why I chose grack as the backend and which I will describe in this tutorial. Using the stock git-http-backend should be quite straightforward though (skip the [[HowTo_configure_Redmine_for_advanced_git_integration#Install-grack|grack installation]] part and get your install with the git-http-backend going (the "git-http-backend manpage":http://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html has some examples), when that's done go on with the [[HowTo_configure_Redmine_for_advanced_git_integration#Access-control|access control]] part).
23 2 Felix Schäfer
24 2 Felix Schäfer
h2. Install grack
25 1 Felix Schäfer
26 3 Felix Schäfer
h3. Get the sources
27 2 Felix Schäfer
28 2 Felix Schäfer
Fetch grack from its "github repository":http://github.com/schacon/grack, I checked out mine to @/var/www/git.myhost.com@:
29 2 Felix Schäfer
30 5 Holger Just
<pre><code class="bash">git clone http://github.com/schacon/grack.git /var/www/git.myhost.com</code></pre>
31 1 Felix Schäfer
32 3 Felix Schäfer
h3. Configuration
33 3 Felix Schäfer
34 2 Felix Schäfer
Edit the @config.ru@ file and adapt it to your local configuration. @project_root@ must contain the path to the directory containing your git repositories, @git_path@ must obviously contain the path to the git, mine looks like this (on gentoo):
35 2 Felix Schäfer
36 2 Felix Schäfer
<pre><code class="ruby">$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
37 2 Felix Schäfer
38 2 Felix Schäfer
use Rack::ShowExceptions
39 2 Felix Schäfer
40 2 Felix Schäfer
require 'lib/git_http'
41 2 Felix Schäfer
42 2 Felix Schäfer
config = {
43 2 Felix Schäfer
  :project_root => "/var/git/git.myhost.com",
44 2 Felix Schäfer
  :git_path => '/usr/libexec/git-core/git',
45 2 Felix Schäfer
  :upload_pack => true,
46 2 Felix Schäfer
  :receive_pack => true,
47 2 Felix Schäfer
}
48 2 Felix Schäfer
49 2 Felix Schäfer
run GitHttp::App.new(config)</code></pre>
50 1 Felix Schäfer
51 3 Felix Schäfer
h3. Integrate with Apache
52 3 Felix Schäfer
53 3 Felix Schäfer
You could obviously use any rack server you like at this point, but the access control mechanism @Redmine.pm@ is written for apache with mod_perl, so you will at least need to reverse proxy your rack server through apache. My rack server of choice is "passenger":http://modrails.com/ (solid performance, apache module, mostly simple configuration) and it is already configured on my system. As passenger installation and configuration is not within the scope of this HowTo, please refer to the "passenger documentation":http://modrails.com/documentation.html or to the passenger installation guide from your distribution.
54 3 Felix Schäfer
55 2 Felix Schäfer
There's a little more work to do here to get passenger to work with this, you will need to create the directories @public@ and @tmp@ in the grack directory. Please also be aware that in the standard configuration, passenger will run the grack application with the same user and group owning the @config.ru@ file. This user must have read- and write-access as needed to the git repositories!
56 2 Felix Schäfer
57 2 Felix Schäfer
The last step is to configure an apache vhost to serve the application:
58 2 Felix Schäfer
59 2 Felix Schäfer
<pre><code class="apache"><VirtualHost yo.ur.i.p:80>
60 2 Felix Schäfer
    ServerName git.myhost.com
61 2 Felix Schäfer
62 2 Felix Schäfer
    ServerAdmin root@myhost.com
63 2 Felix Schäfer
    DocumentRoot "/var/www/git.myhost.com/public"
64 2 Felix Schäfer
65 2 Felix Schäfer
    <Directory "/var/www/git.myhost.com/public">
66 2 Felix Schäfer
        Options None
67 2 Felix Schäfer
        AllowOverride None
68 2 Felix Schäfer
        Order allow,deny
69 2 Felix Schäfer
        Allow from all
70 2 Felix Schäfer
    </Directory>
71 2 Felix Schäfer
</VirtualHost></code></pre>
72 2 Felix Schäfer
73 1 Felix Schäfer
At this point, if you have a repository in @/var/git/git.myhost.com/myrepo@, you should be able to access it through @http://git.myhost.com/myrepo@, for example @git ls-remote http://git.myhost.com/myrepo@ should show you some information about the repository.
74 10 Hallison Vasconcelos Batista
75 10 Hallison Vasconcelos Batista
h2. Install git-webby
76 10 Hallison Vasconcelos Batista
77 10 Hallison Vasconcelos Batista
Follow the instructions available in "repository page":http://git.io/BU7twg that use basically the same instructions described above.
78 3 Felix Schäfer
79 3 Felix Schäfer
h2. Access control
80 3 Felix Schäfer
81 3 Felix Schäfer
You now have a working git server, albeit with no access control. Currently, the shipped perl module for access control @Redmine.pm@ (in @extra/svn/@ in your redmine directory) does not support access control for the git-smart-http protocol, the patch in #4905 aims to implement that.
82 3 Felix Schäfer
83 3 Felix Schäfer
h3. Applying the patch
84 3 Felix Schäfer
85 11 Gregory Bartholomew
Download the latest (or better: correct) version of the patch from #4905 to your redmine directory. In the redmine directory, apply the patch: @patch -p1 < the-patch-file.patch@ should work (if it tells you stuff about being unable to apply a hunk, the patch is incompatible with your @Redmine.pm@ version, if it says other stuff, try @patch -p0 < the-patch-file.patch@ or @patch Redmine.pm < the-patch-file.patch@, if it still borks, ask for advice on #4905).
86 3 Felix Schäfer
87 8 Felix Schäfer
-You will possibly still need to edit the file from here, because the current version of the patch only works for repositories served from @http://git.myhost.com/git/myrepo@ though the above example uses @http://git.myhost.com/myrepo@.- This step isn't needed anymore, the patch has been updated to take the information from the @Location@ block from apache into account.
88 3 Felix Schäfer
89 3 Felix Schäfer
h3. Configuring Apache
90 3 Felix Schäfer
91 9 Loren Sands-Ramshaw
You now have to make Apache aware of your new authentication module (if you already had done this step for subversion integration, you can go to the @Location@ directives directly). Copy or link @Redmine.pm@ (from your @extra/svn/@ directory) to @/usr/lib/perl5/Apache/Redmine.pm@ (ubuntu) or wherever your distribution puts its apache perl modules (e.g. gentoo puts them in @/usr/lib64/perl5/vendor_perl/5.8.8/Apache/@).
92 3 Felix Schäfer
93 3 Felix Schäfer
Having done that, reload apache to make sure everything in the patching phase went well (if not, remove the link or the file create in the step just before and restart apache to get apache back up, try to find the error in your Redmine.pm file). Now edit your vhost configuration to look somewhat like (same as above but with more stuff):
94 3 Felix Schäfer
95 3 Felix Schäfer
<pre><code class="apache"><VirtualHost yo.ur.i.p:80>
96 3 Felix Schäfer
    ServerName git.myhost.com
97 3 Felix Schäfer
98 3 Felix Schäfer
    ServerAdmin root@myhost.com
99 3 Felix Schäfer
    DocumentRoot "/var/www/git.myhost.com/public"
100 3 Felix Schäfer
101 3 Felix Schäfer
    PerlLoadModule Apache::Redmine
102 3 Felix Schäfer
103 3 Felix Schäfer
    <Directory "/var/www/git.myhost.com/public">
104 3 Felix Schäfer
        Options None
105 3 Felix Schäfer
        AllowOverride None
106 3 Felix Schäfer
        Order allow,deny
107 3 Felix Schäfer
        Allow from all
108 3 Felix Schäfer
    </Directory>
109 3 Felix Schäfer
110 3 Felix Schäfer
    <Location "/">
111 3 Felix Schäfer
        AuthType Basic
112 3 Felix Schäfer
        AuthName "Redmine git repositories"
113 3 Felix Schäfer
        Require valid-user
114 3 Felix Schäfer
115 3 Felix Schäfer
        PerlAccessHandler Apache::Authn::Redmine::access_handler
116 3 Felix Schäfer
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
117 3 Felix Schäfer
118 3 Felix Schäfer
        ## for mysql
119 3 Felix Schäfer
        RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
120 3 Felix Schäfer
        ## for postgres
121 3 Felix Schäfer
        # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server"
122 3 Felix Schäfer
        ## for SQLite3
123 3 Felix Schäfer
        # RedmineDSN "DBI:SQLite:dbname=database.db"
124 3 Felix Schäfer
125 3 Felix Schäfer
        RedmineDbUser "redmine"
126 3 Felix Schäfer
        RedmineDbPass "password"
127 3 Felix Schäfer
        RedmineGitSmartHttp yes
128 3 Felix Schäfer
    </Location>
129 3 Felix Schäfer
</VirtualHost></code></pre>
130 3 Felix Schäfer
131 3 Felix Schäfer
Reload your apache, and everything should be good and well :-)
132 3 Felix Schäfer
133 3 Felix Schäfer
h2. Known issues
134 1 Felix Schäfer
135 11 Gregory Bartholomew
If you are using the stock git-http-backend directly under apache and you are finding errors like "Request not supported: '/git/your-git-repo'" in your apache error log, you may need to add "SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER" to the to the list of environment variables that you are setting in your apache configuration.  Unfortionately, this setting may cause redmine to borke.  If so, you will need to set the variable for only the requests that are passed through git-http-backend.  One way to accomplish this is with mod_rewrite.  Below is a sample apache configuration from a Fedora 17 system that uses git-http-backend and mod_rewrite.
136 11 Gregory Bartholomew
137 11 Gregory Bartholomew
In httpd.conf:
138 11 Gregory Bartholomew
139 11 Gregory Bartholomew
<pre><code class="apache">Listen xxx.xxx.xxx.xxx:80
140 11 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:80>
141 11 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
142 11 Gregory Bartholomew
   ServerName servername.domain:80
143 11 Gregory Bartholomew
   Include conf/servername.conf
144 11 Gregory Bartholomew
</VirtualHost>
145 11 Gregory Bartholomew
146 11 Gregory Bartholomew
Listen xxx.xxx.xxx.xxx:443
147 11 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:443>
148 11 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
149 11 Gregory Bartholomew
   ServerName servername.domain:443
150 11 Gregory Bartholomew
   Include conf/servername.conf
151 11 Gregory Bartholomew
   Include conf/ssl.conf
152 11 Gregory Bartholomew
</VirtualHost></code></pre>
153 11 Gregory Bartholomew
154 11 Gregory Bartholomew
In servername.conf:
155 11 Gregory Bartholomew
156 11 Gregory Bartholomew
<pre><code class="apache">PerlLoadModule Apache::Authn::Redmine
157 11 Gregory Bartholomew
158 11 Gregory Bartholomew
SetEnv GIT_PROJECT_ROOT /git-1/repositories
159 11 Gregory Bartholomew
SetEnv GIT_HTTP_EXPORT_ALL
160 11 Gregory Bartholomew
161 11 Gregory Bartholomew
<IfModule mod_rewrite.c>
162 11 Gregory Bartholomew
   RewriteEngine On
163 11 Gregory Bartholomew
164 11 Gregory Bartholomew
   RewriteCond %{HTTPS} ^off$
165 11 Gregory Bartholomew
   RewriteCond %{REQUEST_URI} !^/git-private/
166 11 Gregory Bartholomew
   RewriteRule ^.*$ https://servername.domain$0 [R=301,L]
167 11 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /git-1/repositories/$1 [L]
168 11 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /git-1/repositories/$1 [L]
169 11 Gregory Bartholomew
   RewriteRule ^/git/(.*)$ /usr/libexec/git-core/git-http-backend/$1 [E=REMOTE_USER:$REDIRECT_REMOTE_USER,H=cgi-script,L]
170 11 Gregory Bartholomew
</IfModule>
171 11 Gregory Bartholomew
172 11 Gregory Bartholomew
<Directory /usr/libexec/git-core>
173 11 Gregory Bartholomew
   Options FollowSymLinks ExecCGI
174 11 Gregory Bartholomew
   AllowOverride None
175 11 Gregory Bartholomew
</Directory>
176 11 Gregory Bartholomew
177 11 Gregory Bartholomew
<Directory /git-1/repositories>
178 11 Gregory Bartholomew
   AuthType Basic
179 11 Gregory Bartholomew
   AuthName "CAMPUS"
180 11 Gregory Bartholomew
   AuthBasicProvider external
181 11 Gregory Bartholomew
   AuthExternal pwauth
182 11 Gregory Bartholomew
   Require valid-user
183 11 Gregory Bartholomew
184 11 Gregory Bartholomew
   PerlAccessHandler Apache::Authn::Redmine::access_handler
185 11 Gregory Bartholomew
   PerlAuthenHandler Apache::Authn::Redmine::authen_handler
186 11 Gregory Bartholomew
 
187 11 Gregory Bartholomew
   RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
188 11 Gregory Bartholomew
   RedmineDbUser "redmine"
189 11 Gregory Bartholomew
   # RedmineDbPass "password"
190 11 Gregory Bartholomew
   RedmineGitSmartHttp yes
191 11 Gregory Bartholomew
</Directory>
192 11 Gregory Bartholomew
193 11 Gregory Bartholomew
Alias /git-private /git-1/repositories
194 11 Gregory Bartholomew
195 11 Gregory Bartholomew
<Location /git-private>
196 11 Gregory Bartholomew
   Order deny,allow
197 11 Gregory Bartholomew
   Deny from all
198 11 Gregory Bartholomew
   <Limit GET PROPFIND OPTIONS REPORT>
199 11 Gregory Bartholomew
      Options Indexes FollowSymLinks MultiViews
200 11 Gregory Bartholomew
      Allow from 127.0.0.1
201 11 Gregory Bartholomew
      Allow from localhost
202 11 Gregory Bartholomew
   </Limit>
203 11 Gregory Bartholomew
</Location>
204 11 Gregory Bartholomew
205 11 Gregory Bartholomew
<Directory "/var/www/redmine/public">
206 11 Gregory Bartholomew
   RailsEnv production
207 11 Gregory Bartholomew
   RailsBaseURI /
208 11 Gregory Bartholomew
209 11 Gregory Bartholomew
   Options -MultiViews
210 11 Gregory Bartholomew
   AllowOverride All
211 11 Gregory Bartholomew
</Directory></code></pre>
212 11 Gregory Bartholomew
213 11 Gregory Bartholomew
In conf/ssl.conf:
214 11 Gregory Bartholomew
215 11 Gregory Bartholomew
<pre><code class="apache">LogLevel warn
216 11 Gregory Bartholomew
SSLEngine on
217 11 Gregory Bartholomew
SSLProtocol all -SSLv2
218 11 Gregory Bartholomew
SSLCipherSuite RC4-SHA:AES128-SHA:ALL:!ADH:!EXP:!LOW:!MD5:!SSLV2:!NULL
219 11 Gregory Bartholomew
SSLCertificateFile /etc/pki/tls/certs/your-server.crt
220 11 Gregory Bartholomew
SSLCertificateKeyFile /etc/pki/tls/private/your-server.key
221 11 Gregory Bartholomew
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
222 11 Gregory Bartholomew
SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
223 11 Gregory Bartholomew
224 11 Gregory Bartholomew
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
225 11 Gregory Bartholomew
    SSLOptions +StdEnvVars
226 11 Gregory Bartholomew
</Files>
227 11 Gregory Bartholomew
<Directory "/var/www/cgi-bin">
228 11 Gregory Bartholomew
    SSLOptions +StdEnvVars
229 11 Gregory Bartholomew
</Directory>
230 11 Gregory Bartholomew
231 11 Gregory Bartholomew
SetEnvIf User-Agent ".*MSIE.*" \
232 11 Gregory Bartholomew
         nokeepalive ssl-unclean-shutdown \
233 11 Gregory Bartholomew
         downgrade-1.0 force-response-1.0
234 11 Gregory Bartholomew
</code></pre>
235 11 Gregory Bartholomew
236 11 Gregory Bartholomew
In conf.d/ssl.conf:
237 11 Gregory Bartholomew
238 11 Gregory Bartholomew
<pre><code class="apache">LoadModule ssl_module modules/mod_ssl.so
239 11 Gregory Bartholomew
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
240 11 Gregory Bartholomew
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
241 11 Gregory Bartholomew
SSLSessionCacheTimeout  300
242 11 Gregory Bartholomew
SSLMutex default
243 11 Gregory Bartholomew
SSLRandomSeed startup file:/dev/urandom  256
244 11 Gregory Bartholomew
SSLRandomSeed connect builtin
245 11 Gregory Bartholomew
SSLCryptoDevice builtin
246 11 Gregory Bartholomew
</code></pre>