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

Mr. DTTH, 2013-08-08 04:43

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 17 Mr. DTTH
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. 
8 1 Felix Schäfer
9 17 Mr. DTTH
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.
10 1 Felix Schäfer
11 17 Mr. DTTH
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. 
12 17 Mr. DTTH
13 17 Mr. DTTH
This is a wiki page, feel free to correct or amend anything you find lacking :-) You can also "drop me a line":/users/3866.
14 17 Mr. DTTH
15 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.
16 1 Felix Schäfer
17 1 Felix Schäfer
h2. Prerequisites
18 1 Felix Schäfer
19 1 Felix Schäfer
* Apache with mod_perl (access control)
20 1 Felix Schäfer
* git (version at least 1.6.6)
21 1 Felix Schäfer
* A way to serve git-smart-http
22 10 Hallison Vasconcelos Batista
** 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
23 1 Felix Schäfer
** a rack server if you want to use "grack":http://github.com/schacon/grack (basically a rack wrapper around the right git commands) or
24 10 Hallison Vasconcelos Batista
"git-webby":http://git.io/BU7twg (another implementation based on grack but written in Sinatra).
25 1 Felix Schäfer
26 17 Mr. DTTH
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. 
27 1 Felix Schäfer
28 17 Mr. DTTH
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).
29 17 Mr. DTTH
30 2 Felix Schäfer
h2. Install grack
31 1 Felix Schäfer
32 3 Felix Schäfer
h3. Get the sources
33 2 Felix Schäfer
34 18 Mr. DTTH
Fetch grack from its "github repository":http://github.com/schacon/grack, I checked out mine to @/var/www/grack@:
35 2 Felix Schäfer
36 18 Mr. DTTH
<pre><code class="bash">git clone http://github.com/schacon/grack.git</code></pre>
37 1 Felix Schäfer
38 18 Mr. DTTH
And create a directory for repositories :
39 18 Mr. DTTH
40 18 Mr. DTTH
<pre><code class="bash">
41 18 Mr. DTTH
mkdir /opt/repositories
42 18 Mr. DTTH
mkfir /opt/repositories/git
43 18 Mr. DTTH
chown -R apache:apache /opt/repositories/git
44 18 Mr. DTTH
</code></pre>
45 18 Mr. DTTH
46 2 Felix Schäfer
h3. Configuration
47 2 Felix Schäfer
48 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):
49 2 Felix Schäfer
50 2 Felix Schäfer
<pre><code class="ruby">$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
51 1 Felix Schäfer
52 2 Felix Schäfer
use Rack::ShowExceptions
53 1 Felix Schäfer
54 18 Mr. DTTH
require 'grack'
55 1 Felix Schäfer
56 18 Mr. DTTH
require 'git_adapter'
57 18 Mr. DTTH
58 2 Felix Schäfer
config = {
59 18 Mr. DTTH
  :project_root => "/opt/repositories/git",
60 18 Mr. DTTH
  :git_path => '/usr/bin/git',
61 2 Felix Schäfer
  :upload_pack => true,
62 2 Felix Schäfer
  :receive_pack => true,
63 1 Felix Schäfer
}
64 1 Felix Schäfer
65 1 Felix Schäfer
run GitHttp::App.new(config)</code></pre>
66 3 Felix Schäfer
67 1 Felix Schäfer
h3. Integrate with Apache
68 17 Mr. DTTH
69 1 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. 
70 17 Mr. DTTH
71 1 Felix Schäfer
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. 
72 17 Mr. DTTH
73 17 Mr. DTTH
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.
74 17 Mr. DTTH
75 17 Mr. DTTH
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. 
76 17 Mr. DTTH
77 17 Mr. DTTH
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!
78 2 Felix Schäfer
79 2 Felix Schäfer
The last step is to configure an apache vhost to serve the application:
80 2 Felix Schäfer
81 2 Felix Schäfer
<pre><code class="apache"><VirtualHost yo.ur.i.p:80>
82 2 Felix Schäfer
    ServerName git.myhost.com
83 2 Felix Schäfer
84 2 Felix Schäfer
    ServerAdmin root@myhost.com
85 2 Felix Schäfer
    DocumentRoot "/var/www/git.myhost.com/public"
86 2 Felix Schäfer
87 2 Felix Schäfer
    <Directory "/var/www/git.myhost.com/public">
88 2 Felix Schäfer
        Options None
89 2 Felix Schäfer
        AllowOverride None
90 2 Felix Schäfer
        Order allow,deny
91 2 Felix Schäfer
        Allow from all
92 2 Felix Schäfer
    </Directory>
93 2 Felix Schäfer
</VirtualHost></code></pre>
94 1 Felix Schäfer
95 10 Hallison Vasconcelos Batista
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.
96 10 Hallison Vasconcelos Batista
97 10 Hallison Vasconcelos Batista
h2. Install git-webby
98 3 Felix Schäfer
99 3 Felix Schäfer
Follow the instructions available in "repository page":http://git.io/BU7twg that use basically the same instructions described above.
100 3 Felix Schäfer
101 3 Felix Schäfer
h2. Access control
102 3 Felix Schäfer
103 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.
104 3 Felix Schäfer
105 11 Gregory Bartholomew
h3. Applying the patch
106 1 Felix Schäfer
107 3 Felix Schäfer
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).
108 1 Felix Schäfer
109 1 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.
110 8 Felix Schäfer
111 3 Felix Schäfer
h3. Configuring Apache
112 17 Mr. DTTH
113 3 Felix Schäfer
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). 
114 17 Mr. DTTH
115 17 Mr. DTTH
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/@, fedora puts them in @/usr/lib64/perl5/vendor_perl/Apache/@).
116 3 Felix Schäfer
117 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):
118 3 Felix Schäfer
119 3 Felix Schäfer
<pre><code class="apache"><VirtualHost yo.ur.i.p:80>
120 3 Felix Schäfer
    ServerName git.myhost.com
121 3 Felix Schäfer
122 3 Felix Schäfer
    ServerAdmin root@myhost.com
123 3 Felix Schäfer
    DocumentRoot "/var/www/git.myhost.com/public"
124 3 Felix Schäfer
125 3 Felix Schäfer
    PerlLoadModule Apache::Redmine
126 3 Felix Schäfer
127 3 Felix Schäfer
    <Directory "/var/www/git.myhost.com/public">
128 3 Felix Schäfer
        Options None
129 3 Felix Schäfer
        AllowOverride None
130 3 Felix Schäfer
        Order allow,deny
131 3 Felix Schäfer
        Allow from all
132 3 Felix Schäfer
    </Directory>
133 3 Felix Schäfer
134 3 Felix Schäfer
    <Location "/">
135 3 Felix Schäfer
        AuthType Basic
136 3 Felix Schäfer
        AuthName "Redmine git repositories"
137 3 Felix Schäfer
        Require valid-user
138 3 Felix Schäfer
139 3 Felix Schäfer
        PerlAccessHandler Apache::Authn::Redmine::access_handler
140 3 Felix Schäfer
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
141 3 Felix Schäfer
142 3 Felix Schäfer
        ## for mysql
143 3 Felix Schäfer
        RedmineDSN "DBI:mysql:database=databasename;host=my.db.server"
144 3 Felix Schäfer
        ## for postgres
145 3 Felix Schäfer
        # RedmineDSN "DBI:Pg:dbname=databasename;host=my.db.server"
146 3 Felix Schäfer
        ## for SQLite3
147 3 Felix Schäfer
        # RedmineDSN "DBI:SQLite:dbname=database.db"
148 3 Felix Schäfer
149 3 Felix Schäfer
        RedmineDbUser "redmine"
150 3 Felix Schäfer
        RedmineDbPass "password"
151 1 Felix Schäfer
        RedmineGitSmartHttp yes
152 3 Felix Schäfer
    </Location>
153 1 Felix Schäfer
</VirtualHost></code></pre>
154 1 Felix Schäfer
155 3 Felix Schäfer
Reload your apache, and everything should be good and well :-)
156 3 Felix Schäfer
157 3 Felix Schäfer
h2. Known issues
158 17 Mr. DTTH
159 1 Felix Schäfer
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.  
160 17 Mr. DTTH
161 17 Mr. DTTH
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.
162 13 Gregory Bartholomew
163 13 Gregory Bartholomew
In httpd.conf:
164 13 Gregory Bartholomew
165 13 Gregory Bartholomew
<pre><code class="apache">Listen xxx.xxx.xxx.xxx:80
166 13 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:80>
167 13 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
168 13 Gregory Bartholomew
   ServerName servername.domain:80
169 13 Gregory Bartholomew
   Include conf/servername.conf
170 13 Gregory Bartholomew
</VirtualHost>
171 13 Gregory Bartholomew
172 13 Gregory Bartholomew
Listen xxx.xxx.xxx.xxx:443
173 13 Gregory Bartholomew
<VirtualHost xxx.xxx.xxx.xxx:443>
174 13 Gregory Bartholomew
   DocumentRoot /var/www/redmine/public
175 13 Gregory Bartholomew
   ServerName servername.domain:443
176 13 Gregory Bartholomew
   Include conf/servername.conf
177 13 Gregory Bartholomew
   Include conf/ssl.conf
178 13 Gregory Bartholomew
</VirtualHost></code></pre>
179 13 Gregory Bartholomew
180 13 Gregory Bartholomew
In servername.conf:
181 13 Gregory Bartholomew
182 13 Gregory Bartholomew
<pre><code class="apache">PerlLoadModule Apache::Authn::Redmine
183 13 Gregory Bartholomew
184 13 Gregory Bartholomew
SetEnv GIT_PROJECT_ROOT /git-1/repositories
185 13 Gregory Bartholomew
SetEnv GIT_HTTP_EXPORT_ALL
186 13 Gregory Bartholomew
187 13 Gregory Bartholomew
<IfModule mod_rewrite.c>
188 13 Gregory Bartholomew
   RewriteEngine On
189 13 Gregory Bartholomew
190 13 Gregory Bartholomew
   RewriteCond %{HTTPS} ^off$
191 13 Gregory Bartholomew
   RewriteCond %{REQUEST_URI} !^/git-private/
192 13 Gregory Bartholomew
   RewriteRule ^.*$ https://servername.domain$0 [R=301,L]
193 13 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$ /git-1/repositories/$1 [L]
194 13 Gregory Bartholomew
   RewriteRule ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /git-1/repositories/$1 [L]
195 13 Gregory Bartholomew
   RewriteRule ^/git/(.*)$ /usr/libexec/git-core/git-http-backend/$1 [E=REMOTE_USER:$REDIRECT_REMOTE_USER,H=cgi-script,L]
196 13 Gregory Bartholomew
</IfModule>
197 13 Gregory Bartholomew
198 15 Gregory Bartholomew
<Directory /usr/libexec/git-core>
199 15 Gregory Bartholomew
   <Files "git-http-backend">
200 15 Gregory Bartholomew
      Options +ExecCGI
201 13 Gregory Bartholomew
   </Files>
202 13 Gregory Bartholomew
</Directory>
203 13 Gregory Bartholomew
204 13 Gregory Bartholomew
<Location /git>
205 13 Gregory Bartholomew
   AuthType Basic
206 13 Gregory Bartholomew
   AuthName "CAMPUS"
207 13 Gregory Bartholomew
   AuthBasicProvider external
208 13 Gregory Bartholomew
   AuthExternal pwauth
209 13 Gregory Bartholomew
   Require valid-user
210 13 Gregory Bartholomew
211 13 Gregory Bartholomew
   PerlAccessHandler Apache::Authn::Redmine::access_handler
212 13 Gregory Bartholomew
   PerlAuthenHandler Apache::Authn::Redmine::authen_handler
213 13 Gregory Bartholomew
 
214 13 Gregory Bartholomew
   RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
215 14 Gregory Bartholomew
   RedmineDbUser "redmine" 
216 13 Gregory Bartholomew
   # RedmineDbPass "password"
217 13 Gregory Bartholomew
   RedmineGitSmartHttp yes
218 13 Gregory Bartholomew
</Location>
219 13 Gregory Bartholomew
220 13 Gregory Bartholomew
Alias /git-private /git-1/repositories
221 13 Gregory Bartholomew
222 13 Gregory Bartholomew
<Location /git-private>
223 13 Gregory Bartholomew
   Order deny,allow
224 13 Gregory Bartholomew
   Deny from all
225 13 Gregory Bartholomew
   <Limit GET PROPFIND OPTIONS REPORT>
226 13 Gregory Bartholomew
      Options Indexes FollowSymLinks MultiViews
227 13 Gregory Bartholomew
      Allow from 127.0.0.1
228 13 Gregory Bartholomew
      Allow from localhost
229 13 Gregory Bartholomew
   </Limit>
230 13 Gregory Bartholomew
</Location>
231 13 Gregory Bartholomew
232 13 Gregory Bartholomew
<Directory "/var/www/redmine/public">
233 13 Gregory Bartholomew
   RailsEnv production
234 13 Gregory Bartholomew
   RailsBaseURI /
235 13 Gregory Bartholomew
236 13 Gregory Bartholomew
   Options -MultiViews
237 13 Gregory Bartholomew
   AllowOverride All
238 13 Gregory Bartholomew
</Directory></code></pre>
239 13 Gregory Bartholomew
240 13 Gregory Bartholomew
In conf/ssl.conf:
241 13 Gregory Bartholomew
242 13 Gregory Bartholomew
<pre><code class="apache">LogLevel warn
243 13 Gregory Bartholomew
SSLEngine on
244 13 Gregory Bartholomew
SSLProtocol all -SSLv2
245 13 Gregory Bartholomew
SSLCipherSuite RC4-SHA:AES128-SHA:ALL:!ADH:!EXP:!LOW:!MD5:!SSLV2:!NULL
246 13 Gregory Bartholomew
SSLCertificateFile /etc/pki/tls/certs/your-server.crt
247 13 Gregory Bartholomew
SSLCertificateKeyFile /etc/pki/tls/private/your-server.key
248 13 Gregory Bartholomew
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
249 13 Gregory Bartholomew
SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
250 13 Gregory Bartholomew
251 13 Gregory Bartholomew
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
252 13 Gregory Bartholomew
    SSLOptions +StdEnvVars
253 13 Gregory Bartholomew
</Files>
254 13 Gregory Bartholomew
<Directory "/var/www/cgi-bin">
255 13 Gregory Bartholomew
    SSLOptions +StdEnvVars
256 13 Gregory Bartholomew
</Directory>
257 13 Gregory Bartholomew
258 13 Gregory Bartholomew
SetEnvIf User-Agent ".*MSIE.*" \
259 13 Gregory Bartholomew
         nokeepalive ssl-unclean-shutdown \
260 13 Gregory Bartholomew
         downgrade-1.0 force-response-1.0
261 13 Gregory Bartholomew
</code></pre>
262 13 Gregory Bartholomew
263 13 Gregory Bartholomew
In conf.d/ssl.conf:
264 13 Gregory Bartholomew
265 13 Gregory Bartholomew
<pre><code class="apache">LoadModule ssl_module modules/mod_ssl.so
266 1 Felix Schäfer
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
267 1 Felix Schäfer
SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
268 1 Felix Schäfer
SSLSessionCacheTimeout  300
269 13 Gregory Bartholomew
SSLMutex default
270 13 Gregory Bartholomew
SSLRandomSeed startup file:/dev/urandom  256
271 13 Gregory Bartholomew
SSLRandomSeed connect builtin
272 13 Gregory Bartholomew
SSLCryptoDevice builtin
273 13 Gregory Bartholomew
</code></pre>
274 17 Mr. DTTH
275 17 Mr. DTTH
You will also need to have the perl modules Net::LDAP, Authen::Simple, and Authen::Simple::LDAP installed.  The first two are available in Fedora's default package repositories.  
276 17 Mr. DTTH
277 13 Gregory Bartholomew
The third must be installed after the other two and it must be obtained directly from cpan.  Below are the commands that I used to install these packages on Fedora 17.
278 15 Gregory Bartholomew
279 13 Gregory Bartholomew
yum -y install gcc make perl-LDAP perl-Authen-Simple
280 13 Gregory Bartholomew
cpan
281 1 Felix Schäfer
cpan> install Authen::Simple::LDAP