Install Redmine 346 on Centos 75 » History » Version 10

Franck Michel, 2018-10-03 13:34

1 1 Franck Michel
h1. Installation of Redmine 3.4.6 on CentOS 7.5 + MySQL 8, Apache 2.4, GIT, SVN, LDAP
2 1 Franck Michel
3 1 Franck Michel
{{>toc}} 
4 1 Franck Michel
5 2 Franck Michel
This guide presents an installation procedure for Redmine 3.4.6 on a CentOS 7. I wrote it as I was painfully going through multiple HOW-TOs and forums, fixing one error after the other. As a result, there was much back-and-forth before coming up with the right procedure. I tried to detail things as much as I felt necessary.
6 1 Franck Michel
7 1 Franck Michel
The procedure results of a mix of many different sources for which I give the source URLs in text below.
8 1 Franck Michel
9 1 Franck Michel
Basics like installing CentOS, Apache, or configuring a certificate for Apache are not covered.
10 1 Franck Michel
11 1 Franck Michel
Here is the full configuration I got after this installation:
12 1 Franck Michel
* CentOS Linux release 7.5.1804 (Core) 
13 9 Franck Michel
* Apache 2.4
14 1 Franck Michel
* MySQL 8.0
15 1 Franck Michel
* Redmine 3.4.6
16 1 Franck Michel
* Ruby 2.4.4
17 1 Franck Michel
* Apache Passenger 5.3.4
18 1 Franck Michel
* Integration with Git and Svn
19 1 Franck Michel
* Integration with LDAP
20 9 Franck Michel
21 10 Franck Michel
*IMPORTANT NOTE*:
22 10 Franck Michel
This installation uses **Apache 2.4** in which there are quite some configuration syntax changes compared to 2.2. Directives Allow, Deny, Order are obsolete as of Apache 2.4, but you can still use them for compatibility reasons. However, mixing the new Require directives with the former ones has unexpected results. So, *do not blindly copy/paste examples you shall find on the Web*, most of them are deprecated and will screw your configuration! See "details":https://httpd.apache.org/docs/2.4/en/howto/access.html.
23 1 Franck Michel
24 1 Franck Michel
25 1 Franck Michel
h2. Install MySQL 8 
26 1 Franck Michel
27 1 Franck Michel
Adapted from "this page":https://www.if-not-true-then-false.com/2010/install-mysql-on-fedora-centos-red-hat-rhel/.
28 1 Franck Michel
29 1 Franck Michel
h3. Why MySQL 8?
30 1 Franck Michel
31 1 Franck Michel
Basically, I first mistakenly installed MySQL 8. Then I uninstalled it and installed 5.7, but then for some reason I could not complete the installation of Redmine. So I reinstalled MySQL 8, and it works fine so far. 
32 1 Franck Michel
33 1 Franck Michel
<pre>
34 1 Franck Michel
[As root/sudo]:
35 1 Franck Michel
  yum update -y
36 1 Franck Michel
  yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
37 1 Franck Michel
  yum --disablerepo=mysql80-community install mysql-community-server mysql-devel
38 1 Franck Michel
  systemctl start mysqld.service
39 1 Franck Michel
  systemctl enable mysqld.service
40 1 Franck Michel
</pre>
41 1 Franck Michel
42 1 Franck Michel
If you prefer to stick to MySQL 5.7, replace the yum install line as follows:
43 1 Franck Michel
<pre>
44 1 Franck Michel
  yum --disablerepo=mysql80-community --enablerepo=mysql57-community install mysql-community-server mysql-devel
45 1 Franck Michel
</pre>
46 1 Franck Michel
47 1 Franck Michel
48 1 Franck Michel
Get the password created at installation and run the secure procedure
49 1 Franck Michel
<pre>
50 2 Franck Michel
  grep 'A temporary password is generated for root@localhost' /var/log/mysqld.log | tail -1
51 2 Franck Michel
  /usr/bin/mysql_secure_installation
52 1 Franck Michel
</pre>
53 1 Franck Michel
54 1 Franck Michel
h3. Bind-address
55 1 Franck Michel
56 1 Franck Michel
By default, MySQL 8 has a bind-address set to 127.0.0.1. If you want to use another hostname, or if it is on a different server than Redmine, then set property bind-address appropriately in MySQL config file (likely @/etc/my.cnf@).
57 1 Franck Michel
58 1 Franck Michel
h3. Default password policy
59 1 Franck Michel
60 1 Franck Michel
By default, MySQL 8 sets the default password policy to "caching_sha2_password". Redmine can deal with it but not the Apache module that authenticated git/svn users against the database, and this will generate an error when accessing the repository. Therefore, change the default policy in MySQL config file (likely /etc/my.cnf) by uncommenting the line:
61 1 Franck Michel
<pre>
62 1 Franck Michel
  default-authentication-plugin=mysql_native_password
63 1 Franck Michel
</pre>
64 1 Franck Michel
65 1 Franck Michel
66 1 Franck Michel
h2. Install Ruby 2.4
67 1 Franck Michel
68 1 Franck Michel
Adapted from "this page":https://tecadmin.net/install-ruby-previous-stable-centos/.
69 1 Franck Michel
70 1 Franck Michel
<pre>
71 1 Franck Michel
[As root/sudo]:
72 1 Franck Michel
  yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel \
73 1 Franck Michel
       libyaml-devel libffi-devel openssl-devel make \
74 1 Franck Michel
       bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
75 1 Franck Michel
  curl -sSL https://rvm.io/mpapis.asc | gpg --import -
76 1 Franck Michel
  curl -L get.rvm.io | bash -s stable
77 1 Franck Michel
  source /etc/profile.d/rvm.sh
78 1 Franck Michel
  rvm reload
79 1 Franck Michel
  rvm requirements run
80 1 Franck Michel
  rvm install 2.4
81 1 Franck Michel
  rvm list
82 1 Franck Michel
  ruby --version
83 1 Franck Michel
</pre>
84 1 Franck Michel
    
85 1 Franck Michel
Find the Gem installation path and set the $GEMS variable accordingly, we will use it in later steps, e.g. in my case that was:
86 1 Franck Michel
<pre>
87 1 Franck Michel
  export GEMS=/usr/local/rvm/gems/ruby-2.4.4/gems
88 1 Franck Michel
</pre>
89 1 Franck Michel
90 1 Franck Michel
91 1 Franck Michel
h2. Install Redmine
92 1 Franck Michel
93 1 Franck Michel
Adapted from "this page":https://www.redmine.org/projects/redmine/wiki/RedmineInstall.
94 1 Franck Michel
95 1 Franck Michel
Below, Redmine is installed in directory /home/username/
96 1 Franck Michel
97 1 Franck Michel
h3. Download and untar Redmine, install Ruby packages:
98 1 Franck Michel
99 1 Franck Michel
<pre>
100 1 Franck Michel
[As non-root]:
101 1 Franck Michel
  cd /home/username
102 1 Franck Michel
  wget https://www.redmine.org/releases/redmine-3.4.6.tar.gz
103 1 Franck Michel
  tar xvfz redmine-3.4.6.tar.gz
104 1 Franck Michel
  export REDMINE=/home/username/redmine-3.4.6
105 1 Franck Michel
  cd $REDMINE
106 1 Franck Michel
  cp config/database.yml.example config/database.yml
107 1 Franck Michel
</pre>
108 1 Franck Michel
109 1 Franck Michel
Customize $REDMINE/config/database.yml as explained in the "procedure":https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-3-Database-connection-configuration.
110 1 Franck Michel
111 1 Franck Michel
Install GEMS dependencies:
112 1 Franck Michel
<pre>
113 1 Franck Michel
[As root/sudo]:
114 1 Franck Michel
  cd $REDMINE
115 1 Franck Michel
  gem install bundler
116 1 Franck Michel
  bundle install --without development test
117 1 Franck Michel
  bundle exec rake generate_secret_token
118 1 Franck Michel
  RAILS_ENV=production REDMINE_LANG=en bundle exec rake redmine:load_default_data
119 1 Franck Michel
</pre>
120 1 Franck Michel
121 1 Franck Michel
Let's now make sure that Redmine can start using Webricks (later on we shall Apache instead, but that helps checks if there are any issues so far):
122 1 Franck Michel
<pre>
123 1 Franck Michel
[As root/sudo]:
124 1 Franck Michel
  cd $REDMINE
125 1 Franck Michel
  bundle exec rails server webrick -e production
126 1 Franck Michel
</pre>
127 2 Franck Michel
and browse to http://localhost:3000/. Alternatively, this other command should work exactly the same:
128 1 Franck Michel
<pre>
129 1 Franck Michel
[As root/sudo]:
130 1 Franck Michel
  ruby bin/rails server webrick -e production
131 1 Franck Michel
</pre>
132 1 Franck Michel
133 1 Franck Michel
Note that at this point some HOW-TOs recommand the installation of FastCGI. In this configuation described on this page, I found out that was not necessary.
134 1 Franck Michel
135 1 Franck Michel
136 1 Franck Michel
h3. Install Apache Passenger (an Apache plugin for Ruby environments)
137 1 Franck Michel
138 1 Franck Michel
Adapted from "this page":https://www.vincentliefooghe.net/content/utilisation-apache-passenger-pour-redmine.
139 1 Franck Michel
<pre>
140 1 Franck Michel
[As root/sudo]:
141 1 Franck Michel
  yum install -y httpd-devel libcurl-devel apr-devel apr-util-devel mod_ssl
142 1 Franck Michel
  cd $REDMINE
143 1 Franck Michel
  gem install passenger
144 1 Franck Michel
</pre>
145 1 Franck Michel
146 1 Franck Michel
Find out the installation path of Passenger, and call the Apache module installer, e.g. in my case:
147 1 Franck Michel
<pre>
148 1 Franck Michel
  $GEMS/passenger-5.3.4/bin/passenger-install-apache2-module
149 1 Franck Michel
</pre>
150 1 Franck Michel
151 2 Franck Michel
Follow the steps indicated by the tool. This should include creating an Apache module configuration file. I created /etc/httpd/conf.modules.d/pasenger.conf, you should adapt the Ruby and Passenger paths according to the versions installed above:
152 1 Franck Michel
<pre>
153 1 Franck Michel
  LoadModule passenger_module /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4/buildout/apache2/mod_passenger.so
154 1 Franck Michel
  <IfModule mod_passenger.c>
155 1 Franck Michel
    PassengerRoot /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4
156 1 Franck Michel
    PassengerDefaultRuby /usr/local/rvm/gems/ruby-2.4.4/wrappers/ruby
157 1 Franck Michel
  </IfModule>
158 1 Franck Michel
</pre>
159 1 Franck Michel
160 2 Franck Michel
h3. Configure Apache as the front end for Redmine
161 1 Franck Michel
162 1 Franck Michel
As root, create a virtual host entry in /etc/httpd/conf.d/redmine.conf (adapt the paths to your installation):
163 1 Franck Michel
<pre>
164 1 Franck Michel
    <VirtualHost *:80>
165 1 Franck Michel
        ServerName youserver.domain.org
166 1 Franck Michel
        DocumentRoot "/home/username/redmine-3.4.6/public"
167 1 Franck Michel
        
168 1 Franck Michel
        ErrorLog logs/redmine_error_log
169 1 Franck Michel
        LogLevel warn
170 1 Franck Michel
171 1 Franck Michel
        <Directory "/home/username/redmine-3.4.6/public">
172 1 Franck Michel
            Options Indexes ExecCGI FollowSymLinks
173 1 Franck Michel
            Require all granted
174 1 Franck Michel
            AllowOverride all
175 1 Franck Michel
        </Directory>
176 1 Franck Michel
    </VirtualHost>
177 1 Franck Michel
</pre>
178 1 Franck Michel
179 1 Franck Michel
Give Apache write access to some directories. Check the Apache user by looking for propertues @User@ and @Group@ in the Apache main configuraton file (in /etc/httpd/conf or /etc/apache/conf). This is "apache" in my case, but could also be "www-data" in different packagings.
180 1 Franck Michel
<pre>
181 1 Franck Michel
  cd $REDMINE
182 1 Franck Michel
  chown -R apache:apache files log tmp vendor
183 1 Franck Michel
</pre>
184 1 Franck Michel
Restart apache:
185 1 Franck Michel
<pre>
186 1 Franck Michel
  systemctl restart httpd
187 1 Franck Michel
</pre>
188 1 Franck Michel
There you go: browse to http://youserver.domain.org, you should get the login page. Hurah!
189 1 Franck Michel
Login with default login "admin" and password "admin", and of course, change the admin password immediatly.
190 1 Franck Michel
191 1 Franck Michel
192 1 Franck Michel
h3. Email config with sendmail
193 1 Franck Michel
194 1 Franck Michel
As non-root, edit @$REDMINE/config/configuration.yml@ and uncomment the 2 lines concerning sendmail:
195 1 Franck Michel
<pre>
196 1 Franck Michel
    email_delivery:
197 1 Franck Michel
      delivery_method:sendmail
198 1 Franck Michel
</pre>
199 1 Franck Michel
200 1 Franck Michel
And install sendmail if it is not yet installed:
201 1 Franck Michel
<pre>
202 1 Franck Michel
[As root/sudo]:
203 1 Franck Michel
  yum install -y sendmail sendmail-cf
204 1 Franck Michel
</pre>
205 1 Franck Michel
206 1 Franck Michel
h3. LDAP authentication
207 1 Franck Michel
208 1 Franck Michel
Ask the LDAP details to your administrator and set them in the Web interface: Admin > LDAP authentication
209 1 Franck Michel
210 5 Franck Michel
h2. SCM Repos integration - Preliminary
211 1 Franck Michel
212 1 Franck Michel
Enable the Web Service for repository management: go to "Administration -> Settings -> Repository" and check "Enable WS for repository management", then clik on "Generate a key" to create a new WS key and save the key that you will use below.
213 1 Franck Michel
214 1 Franck Michel
The reposman.rb script needs @activeresource@ to work, run this (if this is already installed, this will just do nothing):
215 1 Franck Michel
<pre>
216 1 Franck Michel
[As root]:
217 1 Franck Michel
    cd $REDMINE
218 1 Franck Michel
    gem install activeresource
219 1 Franck Michel
</pre>
220 1 Franck Michel
    
221 1 Franck Michel
To restrict the access to the WS, secure the Apache configuration by adding this to the 
222 1 Franck Michel
VirtualHost configuration (/etc/httpd/conf.d/redmine.conf above). Reminder: this is an Apache 2.4 syntax.
223 1 Franck Michel
<pre>
224 1 Franck Michel
   <Location /sys>
225 1 Franck Michel
      Require host youserver.domain.org sparks-vm5.i3s.unice.fr localhost
226 1 Franck Michel
      Require all denied
227 1 Franck Michel
   </Location>
228 1 Franck Michel
</pre>
229 1 Franck Michel
230 1 Franck Michel
Install Apache packages needed to use the database for authentication (with Git as well as Svn):
231 1 Franck Michel
<pre>
232 1 Franck Michel
[As root/sudo]:
233 1 Franck Michel
    yum install -y mod_perl perl-DBI perl-DBD-MySQL perl-Digest-SHA1 perl-LDAP
234 1 Franck Michel
</pre>
235 1 Franck Michel
236 2 Franck Michel
Unlike in other HOW-TOs, there should be no need to use CPAN to install the DBI Perl module for Apache, it must have been installed with perl-DBI. Check where @DBI.pm@ was installed. In my case, it was in /usr/lib64/perl5/vendor_perl, not in /usr/lib/perl5/Apache as often mentioned in other HOW-TOs. Therefore, in the config below, I simply changed the "PerlLoadModule Apache::DBI" (that I found in many examples) into "PerlLoadModule DBI".
237 1 Franck Michel
238 2 Franck Michel
Also, link $REDMINE/extra/svn/Redmine.pm into Apache's PERL scripts. You should check the appropriate path, in my case this is /usr/lib64/perl5/vendor_perl/.
239 1 Franck Michel
<pre>
240 1 Franck Michel
[As root/sudo]:
241 1 Franck Michel
    mkdir /usr/lib64/perl5/vendor_perl/Apache/Authn
242 1 Franck Michel
    ln -s $REDMINE/extra/svn/Redmine.pm /usr/lib64/perl5/vendor_perl/Authn/Apache
243 1 Franck Michel
</pre>
244 1 Franck Michel
245 1 Franck Michel
Optional: to allow for LDAP authentication, install the Simple LDAP modules with CPAN. In my cases, it required dependencies Modules::Build and Params::Validate:
246 1 Franck Michel
<pre>
247 1 Franck Michel
[As root/sudo]:
248 1 Franck Michel
    cpan
249 1 Franck Michel
    install Modules::Build
250 1 Franck Michel
    install Params::Validate
251 1 Franck Michel
    install Authen::Simple::LDAP
252 1 Franck Michel
</pre>
253 1 Franck Michel
254 1 Franck Michel
Update the Apache Redmine configuration (redmine.conf) as shown below:
255 1 Franck Michel
<pre>
256 1 Franck Michel
    PerlLoadModule Apache::Authn::Redmine
257 1 Franck Michel
    PerlLoadModule Redmine
258 1 Franck Michel
259 1 Franck Michel
    # Enable connection pooling (useful for checkouts with many files)
260 1 Franck Michel
    PerlModule DBI
261 1 Franck Michel
    PerlOptions +GlobalRequest
262 1 Franck Michel
263 1 Franck Michel
    # Enable LDAP(S) authentication (optional)
264 1 Franck Michel
    PerlLoadModule Authen::Simple::LDAP
265 1 Franck Michel
    PerlLoadModule IO::Socket::SSL
266 1 Franck Michel
</pre>
267 1 Franck Michel
268 1 Franck Michel
*Possible authentication issue*: MySQL 8 sets the default password policy to "caching_sha2_password". @Redmine.pm@ is not compatible with that and will generate a weird error in the Apache redmine_error_log, like this:
269 1 Franck Michel
<pre>
270 1 Franck Michel
    Can't call method "prepare" on an undefined value at /usr/lib64/perl5/vendor_perl/Apache/Redmine.pm line 364, <DATA> line 747.\n
271 1 Franck Michel
</pre>
272 1 Franck Michel
A closer look at the regular Apache error_log shows another error:
273 1 Franck Michel
<pre>
274 1 Franck Michel
    DBI connect('database=redmine;host=127.0.0.1','redmine',...) failed: Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory at /usr/lib64/perl5/vendor_perl/Apache/Redmine.pm line 557.
275 1 Franck Michel
</pre>
276 1 Franck Michel
277 1 Franck Michel
To fix this, change MySQL's password policy for user redmine (found "here":https://my.oschina.net/johnsken/blog/1840348):
278 1 Franck Michel
<pre>
279 1 Franck Michel
    mysql -uroot -p
280 1 Franck Michel
    mysql> show variables like 'default_authentication_plugin';
281 1 Franck Michel
    +-------------------------------+-----------------------+
282 1 Franck Michel
    | Variable_name                 | Value                 |
283 1 Franck Michel
    +-------------------------------+-----------------------+
284 1 Franck Michel
    | default_authentication_plugin | caching_sha2_password |
285 1 Franck Michel
    +-------------------------------+-----------------------+
286 1 Franck Michel
287 1 Franck Michel
    mysql> select host,user,plugin from mysql.user;
288 1 Franck Michel
    +-----------+------------------+-----------------------+
289 1 Franck Michel
    | host      | user             | plugin                |
290 1 Franck Michel
    +-----------+------------------+-----------------------+
291 1 Franck Michel
    | localhost | mysql.infoschema | caching_sha2_password |
292 1 Franck Michel
    | localhost | mysql.session    | caching_sha2_password |
293 1 Franck Michel
    | localhost | mysql.sys        | caching_sha2_password |
294 1 Franck Michel
    | localhost | redmine          | caching_sha2_password |
295 1 Franck Michel
    | localhost | root             | caching_sha2_password |
296 1 Franck Michel
    +-----------+------------------+-----------------------+
297 1 Franck Michel
298 1 Franck Michel
    mysql> ALTER USER 'redmine'@'localhost' IDENTIFIED WITH mysql_native_password BY '<YOUR REDMINE PASSWORD>';
299 1 Franck Michel
    Query OK, 0 rows affected (0,10 sec)
300 1 Franck Michel
301 1 Franck Michel
    mysql> select host,user,plugin from mysql.user;
302 1 Franck Michel
    +-----------+------------------+-----------------------+
303 1 Franck Michel
    | host      | user             | plugin                |
304 1 Franck Michel
    +-----------+------------------+-----------------------+
305 1 Franck Michel
    | localhost | mysql.infoschema | caching_sha2_password |
306 1 Franck Michel
    | localhost | mysql.session    | caching_sha2_password |
307 1 Franck Michel
    | localhost | mysql.sys        | caching_sha2_password |
308 1 Franck Michel
    | localhost | redmine          | mysql_native_password |
309 1 Franck Michel
    | localhost | root             | caching_sha2_password |
310 1 Franck Michel
    +-----------+------------------+-----------------------+
311 1 Franck Michel
</pre>
312 1 Franck Michel
313 1 Franck Michel
h2. SVN integration
314 1 Franck Michel
315 1 Franck Michel
h3. Repositories access control with Apache 2.4 with mod_dav_svn and mod_perl
316 1 Franck Michel
317 1 Franck Michel
Adapted from "this page":https://www.redmine.org/projects/redmine/wiki/HowTo_configure_Redmine_for_advanced_Subversion_integration, section "Using apache/mod_dav_svn/mod_perl".
318 1 Franck Michel
319 1 Franck Michel
Make sure SVN CLI packages are already installed.
320 1 Franck Michel
<pre>
321 1 Franck Michel
    yum -y install svn
322 1 Franck Michel
</pre>
323 1 Franck Michel
324 1 Franck Michel
Create the directory where all SVN repos will/have to be stored:
325 1 Franck Michel
<pre>
326 1 Franck Michel
[As root/sudo]:
327 1 Franck Michel
    export SVN=/var/lib/svn
328 1 Franck Michel
    mkdir $SVN
329 1 Franck Michel
    chown apache:apache $SVN
330 1 Franck Michel
    chmod 0750 $SVN
331 1 Franck Michel
</pre>
332 1 Franck Michel
333 3 Franck Michel
Then, there are two options to attach an SVN repository to a project:
334 1 Franck Michel
335 4 Franck Michel
_1. Explicitly attach a repo to a project_
336 3 Franck Michel
337 7 Franck Michel
Copy an existing repository to $SVN, or create an new empty repository, and change its owner, like this:
338 3 Franck Michel
<pre>
339 1 Franck Michel
    svnadmin create $SVN/<repo_name>
340 8 Franck Michel
    chown -R apache:apache $SVN/<repo_name>
341 3 Franck Michel
</pre>
342 3 Franck Michel
343 3 Franck Michel
Then, on the web interface, select the project you want to attach the repo to, go to Settings > Repositories > New repository. The repo URL should be @/var/lib/svn/<repo_name>@ in the example above.
344 1 Franck Michel
345 3 Franck Michel
346 6 Franck Michel
_2. Automatically create SVN repos for declared projects_
347 6 Franck Michel
You can also ask Redmine to automatically create SVN repos for each declared project: the new repo will be name after the project name.
348 3 Franck Michel
349 1 Franck Michel
<pre>
350 1 Franck Michel
[As root/sudo]:
351 1 Franck Michel
    cd $REDMINE/extra/svn
352 1 Franck Michel
    ruby reposman.rb --redmine https://youserver.domain.org --svn-dir $SVN \
353 1 Franck Michel
                     --owner apache --url http://youserver.domain.org/svn/ \
354 1 Franck Michel
                     --verbose --key=<ws_key>
355 1 Franck Michel
</pre>
356 1 Franck Michel
357 1 Franck Michel
In my case, I had declared a single test project, here is the result:
358 1 Franck Michel
<pre>
359 1 Franck Michel
    querying Redmine for active projects with repository module enabled...
360 1 Franck Michel
    retrieved  projects
361 1 Franck Michel
    processing project test (test)
362 1 Franck Michel
        repository /var/lib/svn/test created
363 1 Franck Michel
        repository /var/lib/svn/test registered in Redmine with url http://youserver.domain.org/svn/test
364 1 Franck Michel
</pre>
365 1 Franck Michel
366 1 Franck Michel
h3. SVN access from Apache
367 1 Franck Michel
368 2 Franck Michel
At this point, we have Redmine configured to create repositories for existing projects. We now have to configure Apache to allow browsing the repos from outside Redmine (typically with an SVN client but also simply with a web browser).
369 1 Franck Michel
370 1 Franck Michel
Install Apache needed packages: 
371 1 Franck Michel
<pre>
372 1 Franck Michel
[As root/sudo]:
373 1 Franck Michel
    yum install -y mod_dav_svn
374 1 Franck Michel
</pre>
375 1 Franck Michel
376 1 Franck Michel
The installation should add loading of DAV and SVN modules to the Apache configuration. Check and fix this if necessary:
377 1 Franck Michel
<pre>
378 1 Franck Michel
    $ cat /etc/httpd/conf.modules.d/00-dav.conf 
379 1 Franck Michel
    LoadModule dav_module modules/mod_dav.so
380 1 Franck Michel
    LoadModule dav_fs_module modules/mod_dav_fs.so
381 1 Franck Michel
    LoadModule dav_lock_module modules/mod_dav_lock.so
382 1 Franck Michel
383 1 Franck Michel
    $ cat /etc/httpd/conf.modules.d/10-subversion.conf 
384 1 Franck Michel
    LoadModule dav_svn_module     modules/mod_dav_svn.so
385 1 Franck Michel
    LoadModule authz_svn_module   modules/mod_authz_svn.so
386 1 Franck Michel
    LoadModule dontdothat_module  modules/mod_dontdothat.so
387 1 Franck Michel
</pre>
388 1 Franck Michel
389 1 Franck Michel
Update the Apache Redmine configuration (redmine.conf) as shown below. Note that there is no need for a <Location /svn-private> section as shown in older HOW-TOs.
390 1 Franck Michel
391 1 Franck Michel
<pre>
392 1 Franck Michel
    # Enable SVN access from outside Redmine (web browser, SVN client)
393 1 Franck Michel
    <Location /svn>
394 1 Franck Michel
        DAV svn
395 1 Franck Michel
        SVNParentPath "/var/lib/svn"
396 1 Franck Michel
        SVNReposName "Subversion Repository" 
397 1 Franck Michel
        Require all denied
398 1 Franck Michel
399 1 Franck Michel
        # Uncomment the following line when using subversion 1.8 or newer
400 1 Franck Michel
        # (see http://subversion.apache.org/docs/release-notes/1.8.html#serf-skelta-default)
401 1 Franck Michel
        # SVNAllowBulkUpdates Prefer
402 1 Franck Michel
403 1 Franck Michel
        # If a client tries to svn update which involves updating many files,
404 1 Franck Michel
        # the update request might result in an error Server sent unexpected
405 1 Franck Michel
        # return value (413 Request Entity Too Large) in response to REPORT
406 1 Franck Michel
        # request, because the size of the update request exceeds the limit
407 1 Franck Michel
        # allowed by the server. You can avoid this error by disabling the
408 1 Franck Michel
        # request size limit by adding the line LimitXMLRequestBody 0
409 1 Franck Michel
        LimitXMLRequestBody 0
410 1 Franck Michel
411 1 Franck Michel
        # Only check Authentication for root path, nor again for recursive folder.
412 1 Franck Michel
        # Redmine core does only permit access on repository level, so this
413 1 Franck Michel
        # doesn't hurt security. On the other hand it does boost performance a lot!
414 1 Franck Michel
        SVNPathAuthz off
415 1 Franck Michel
416 1 Franck Michel
        PerlAccessHandler Apache::Authn::Redmine::access_handler
417 1 Franck Michel
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
418 1 Franck Michel
        AuthType Basic
419 1 Franck Michel
        AuthName "Redmine SVN Repository" 
420 1 Franck Michel
        AuthUserFile /dev/null
421 1 Franck Michel
422 1 Franck Michel
        # Read-only access    
423 1 Franck Michel
        <Limit GET PROPFIND OPTIONS REPORT>
424 1 Franck Michel
            # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2)
425 1 Franck Michel
            <RequireAny>
426 1 Franck Michel
                Require valid-user
427 1 Franck Michel
                Require local
428 1 Franck Michel
            </RequireAny>
429 1 Franck Michel
        </Limit>
430 1 Franck Michel
431 1 Franck Michel
        # Write access (methods POST, PUT)
432 1 Franck Michel
        <LimitExcept GET PROPFIND OPTIONS REPORT>
433 1 Franck Michel
            Require valid-user
434 1 Franck Michel
        </LimitExcept>
435 1 Franck Michel
436 1 Franck Michel
        # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server
437 1 Franck Michel
        RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>"
438 1 Franck Michel
        RedmineDbUser "redmine" 
439 1 Franck Michel
        RedmineDbPass "<password>" 
440 1 Franck Michel
    </Location>
441 1 Franck Michel
</pre>
442 1 Franck Michel
443 1 Franck Michel
h2. Git integration
444 1 Franck Michel
445 1 Franck Michel
Create the directory where all GIT repos will/have to be stored:
446 1 Franck Michel
<pre>
447 1 Franck Michel
[As root/sudo]:
448 1 Franck Michel
    export GIT=/var/lib/git
449 1 Franck Michel
    mkdir $GIT
450 1 Franck Michel
    chown apache:apache $GIT
451 1 Franck Michel
    chmod 0750 $GIT
452 1 Franck Michel
</pre>
453 1 Franck Michel
454 2 Franck Michel
Note: Redmine can only deal with bare Git repositories (see http://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/). You can get a bare Git repo in two ways: "git init --bare" or "git close --bare ...".
455 1 Franck Michel
456 2 Franck Michel
In the case of a fresh new local repository (git init --bare), Redmine will be able to display its content only after the first commit. Try this:
457 1 Franck Michel
458 1 Franck Michel
<pre>
459 1 Franck Michel
[As root/sudo]:
460 1 Franck Michel
    # Create a local bare repo
461 1 Franck Michel
    mkdir -p $GIT/test.git
462 1 Franck Michel
    chown apache:apache $GIT/test.git/
463 1 Franck Michel
    cd $GIT/test.git/
464 1 Franck Michel
    git init --bare
465 1 Franck Michel
466 1 Franck Michel
    # Create another repo as a clone of the previous one, make one commit and push.
467 1 Franck Michel
    cd ..
468 1 Franck Michel
    mkdir -p $GIT/test.local.git
469 1 Franck Michel
    cd $GIT/test.local.git/
470 1 Franck Michel
    git init
471 1 Franck Michel
    touch TEST.txt
472 1 Franck Michel
    git add TEST.txt
473 1 Franck Michel
    git commit -m "repository initalization" 
474 1 Franck Michel
    git push $GIT/test.git/ master
475 1 Franck Michel
</pre>
476 1 Franck Michel
477 1 Franck Michel
Now that there is commit in your bare repo, you can browse it via Redmine: create a project and attach test.git as the main repo. Then go to the Repository tab, you should see the log of the first commit.
478 1 Franck Michel
479 1 Franck Michel
Update the Apache Redmine configuration (redmine.conf) as shown below. Note that there is no need for a <Location /git-private> section as shown in older HOW-TOs.
480 1 Franck Michel
481 1 Franck Michel
<pre>
482 1 Franck Michel
    #--- Enable Git access from outside Redmine
483 1 Franck Michel
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
484 1 Franck Michel
    
485 1 Franck Michel
    SetEnv GIT_PROJECT_ROOT /var/lib/git
486 1 Franck Michel
    SetEnv GIT_HTTP_EXPORT_ALL
487 1 Franck Michel
488 1 Franck Michel
    <Location /git>
489 1 Franck Michel
        SSLRequireSSL
490 1 Franck Michel
        PerlAccessHandler Apache::Authn::Redmine::access_handler
491 1 Franck Michel
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
492 1 Franck Michel
        AuthType Basic
493 1 Franck Michel
        AuthName "Redmine Git Repository" 
494 1 Franck Michel
        AuthUserFile /dev/null
495 1 Franck Michel
        Require all denied
496 1 Franck Michel
        
497 1 Franck Michel
        <Limit GET PROPFIND OPTIONS REPORT>
498 1 Franck Michel
            Options Indexes FollowSymLinks MultiViews
499 1 Franck Michel
            # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2)
500 1 Franck Michel
            <RequireAny>
501 1 Franck Michel
                Require valid-user
502 1 Franck Michel
                Require local
503 1 Franck Michel
            </RequireAny>
504 1 Franck Michel
        </Limit>
505 1 Franck Michel
506 1 Franck Michel
        # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server
507 1 Franck Michel
        RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>"
508 1 Franck Michel
        RedmineDbUser "redmine" 
509 1 Franck Michel
        RedmineDbPass "<password>"
510 1 Franck Michel
        RedmineGitSmartHttp yes
511 1 Franck Michel
    </Location>
512 1 Franck Michel
</pre>