Install Redmine 346 on Centos 75 » History » Version 6

Franck Michel, 2018-10-02 14:45

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 1 Franck Michel
* Apache 2.4 (this is important as there were quite some configuration syntax changes since 2.2)
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 1 Franck Michel
21 1 Franck Michel
22 1 Franck Michel
h2. Install MySQL 8 
23 1 Franck Michel
24 1 Franck Michel
Adapted from "this page":https://www.if-not-true-then-false.com/2010/install-mysql-on-fedora-centos-red-hat-rhel/.
25 1 Franck Michel
26 1 Franck Michel
h3. Why MySQL 8?
27 1 Franck Michel
28 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. 
29 1 Franck Michel
30 1 Franck Michel
<pre>
31 1 Franck Michel
[As root/sudo]:
32 1 Franck Michel
  yum update -y
33 1 Franck Michel
  yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
34 1 Franck Michel
  yum --disablerepo=mysql80-community install mysql-community-server mysql-devel
35 1 Franck Michel
  systemctl start mysqld.service
36 1 Franck Michel
  systemctl enable mysqld.service
37 1 Franck Michel
</pre>
38 1 Franck Michel
39 1 Franck Michel
If you prefer to stick to MySQL 5.7, replace the yum install line as follows:
40 1 Franck Michel
<pre>
41 1 Franck Michel
  yum --disablerepo=mysql80-community --enablerepo=mysql57-community install mysql-community-server mysql-devel
42 1 Franck Michel
</pre>
43 1 Franck Michel
44 1 Franck Michel
45 1 Franck Michel
Get the password created at installation and run the secure procedure
46 1 Franck Michel
<pre>
47 2 Franck Michel
  grep 'A temporary password is generated for root@localhost' /var/log/mysqld.log | tail -1
48 2 Franck Michel
  /usr/bin/mysql_secure_installation
49 1 Franck Michel
</pre>
50 1 Franck Michel
51 1 Franck Michel
h3. Bind-address
52 1 Franck Michel
53 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@).
54 1 Franck Michel
55 1 Franck Michel
h3. Default password policy
56 1 Franck Michel
57 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:
58 1 Franck Michel
<pre>
59 1 Franck Michel
  default-authentication-plugin=mysql_native_password
60 1 Franck Michel
</pre>
61 1 Franck Michel
62 1 Franck Michel
63 1 Franck Michel
h2. Install Ruby 2.4
64 1 Franck Michel
65 1 Franck Michel
Adapted from "this page":https://tecadmin.net/install-ruby-previous-stable-centos/.
66 1 Franck Michel
67 1 Franck Michel
<pre>
68 1 Franck Michel
[As root/sudo]:
69 1 Franck Michel
  yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel \
70 1 Franck Michel
       libyaml-devel libffi-devel openssl-devel make \
71 1 Franck Michel
       bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
72 1 Franck Michel
  curl -sSL https://rvm.io/mpapis.asc | gpg --import -
73 1 Franck Michel
  curl -L get.rvm.io | bash -s stable
74 1 Franck Michel
  source /etc/profile.d/rvm.sh
75 1 Franck Michel
  rvm reload
76 1 Franck Michel
  rvm requirements run
77 1 Franck Michel
  rvm install 2.4
78 1 Franck Michel
  rvm list
79 1 Franck Michel
  ruby --version
80 1 Franck Michel
</pre>
81 1 Franck Michel
    
82 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:
83 1 Franck Michel
<pre>
84 1 Franck Michel
  export GEMS=/usr/local/rvm/gems/ruby-2.4.4/gems
85 1 Franck Michel
</pre>
86 1 Franck Michel
87 1 Franck Michel
88 1 Franck Michel
h2. Install Redmine
89 1 Franck Michel
90 1 Franck Michel
Adapted from "this page":https://www.redmine.org/projects/redmine/wiki/RedmineInstall.
91 1 Franck Michel
92 1 Franck Michel
Below, Redmine is installed in directory /home/username/
93 1 Franck Michel
94 1 Franck Michel
h3. Download and untar Redmine, install Ruby packages:
95 1 Franck Michel
96 1 Franck Michel
<pre>
97 1 Franck Michel
[As non-root]:
98 1 Franck Michel
  cd /home/username
99 1 Franck Michel
  wget https://www.redmine.org/releases/redmine-3.4.6.tar.gz
100 1 Franck Michel
  tar xvfz redmine-3.4.6.tar.gz
101 1 Franck Michel
  export REDMINE=/home/username/redmine-3.4.6
102 1 Franck Michel
  cd $REDMINE
103 1 Franck Michel
  cp config/database.yml.example config/database.yml
104 1 Franck Michel
</pre>
105 1 Franck Michel
106 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.
107 1 Franck Michel
108 1 Franck Michel
Install GEMS dependencies:
109 1 Franck Michel
<pre>
110 1 Franck Michel
[As root/sudo]:
111 1 Franck Michel
  cd $REDMINE
112 1 Franck Michel
  gem install bundler
113 1 Franck Michel
  bundle install --without development test
114 1 Franck Michel
  bundle exec rake generate_secret_token
115 1 Franck Michel
  RAILS_ENV=production REDMINE_LANG=en bundle exec rake redmine:load_default_data
116 1 Franck Michel
</pre>
117 1 Franck Michel
118 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):
119 1 Franck Michel
<pre>
120 1 Franck Michel
[As root/sudo]:
121 1 Franck Michel
  cd $REDMINE
122 1 Franck Michel
  bundle exec rails server webrick -e production
123 1 Franck Michel
</pre>
124 2 Franck Michel
and browse to http://localhost:3000/. Alternatively, this other command should work exactly the same:
125 1 Franck Michel
<pre>
126 1 Franck Michel
[As root/sudo]:
127 1 Franck Michel
  ruby bin/rails server webrick -e production
128 1 Franck Michel
</pre>
129 1 Franck Michel
130 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.
131 1 Franck Michel
132 1 Franck Michel
133 1 Franck Michel
h3. Install Apache Passenger (an Apache plugin for Ruby environments)
134 1 Franck Michel
135 1 Franck Michel
Adapted from "this page":https://www.vincentliefooghe.net/content/utilisation-apache-passenger-pour-redmine.
136 1 Franck Michel
<pre>
137 1 Franck Michel
[As root/sudo]:
138 1 Franck Michel
  yum install -y httpd-devel libcurl-devel apr-devel apr-util-devel mod_ssl
139 1 Franck Michel
  cd $REDMINE
140 1 Franck Michel
  gem install passenger
141 1 Franck Michel
</pre>
142 1 Franck Michel
143 1 Franck Michel
Find out the installation path of Passenger, and call the Apache module installer, e.g. in my case:
144 1 Franck Michel
<pre>
145 1 Franck Michel
  $GEMS/passenger-5.3.4/bin/passenger-install-apache2-module
146 1 Franck Michel
</pre>
147 1 Franck Michel
148 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:
149 1 Franck Michel
<pre>
150 1 Franck Michel
  LoadModule passenger_module /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4/buildout/apache2/mod_passenger.so
151 1 Franck Michel
  <IfModule mod_passenger.c>
152 1 Franck Michel
    PassengerRoot /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4
153 1 Franck Michel
    PassengerDefaultRuby /usr/local/rvm/gems/ruby-2.4.4/wrappers/ruby
154 1 Franck Michel
  </IfModule>
155 1 Franck Michel
</pre>
156 1 Franck Michel
157 1 Franck Michel
h3. Configure Apache as the front end for Redmine
158 1 Franck Michel
159 1 Franck Michel
*IMPORTANT NOTE*:
160 2 Franck Michel
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.
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 3 Franck Michel
Copy an existing repository to $SVN, or create an new empty repository, like this:
338 3 Franck Michel
<pre>
339 3 Franck Michel
    svnadmin create $SVN/<repo_name>
340 3 Franck Michel
</pre>
341 3 Franck Michel
342 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.
343 1 Franck Michel
344 3 Franck Michel
345 6 Franck Michel
_2. Automatically create SVN repos for declared projects_
346 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.
347 3 Franck Michel
348 1 Franck Michel
<pre>
349 1 Franck Michel
[As root/sudo]:
350 1 Franck Michel
    cd $REDMINE/extra/svn
351 1 Franck Michel
    ruby reposman.rb --redmine https://youserver.domain.org --svn-dir $SVN \
352 1 Franck Michel
                     --owner apache --url http://youserver.domain.org/svn/ \
353 1 Franck Michel
                     --verbose --key=<ws_key>
354 1 Franck Michel
</pre>
355 1 Franck Michel
356 1 Franck Michel
In my case, I had declared a single test project, here is the result:
357 1 Franck Michel
<pre>
358 1 Franck Michel
    querying Redmine for active projects with repository module enabled...
359 1 Franck Michel
    retrieved  projects
360 1 Franck Michel
    processing project test (test)
361 1 Franck Michel
        repository /var/lib/svn/test created
362 1 Franck Michel
        repository /var/lib/svn/test registered in Redmine with url http://youserver.domain.org/svn/test
363 1 Franck Michel
</pre>
364 1 Franck Michel
365 1 Franck Michel
h3. SVN access from Apache
366 1 Franck Michel
367 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).
368 1 Franck Michel
369 1 Franck Michel
Install Apache needed packages: 
370 1 Franck Michel
<pre>
371 1 Franck Michel
[As root/sudo]:
372 1 Franck Michel
    yum install -y mod_dav_svn
373 1 Franck Michel
</pre>
374 1 Franck Michel
375 1 Franck Michel
The installation should add loading of DAV and SVN modules to the Apache configuration. Check and fix this if necessary:
376 1 Franck Michel
<pre>
377 1 Franck Michel
    $ cat /etc/httpd/conf.modules.d/00-dav.conf 
378 1 Franck Michel
    LoadModule dav_module modules/mod_dav.so
379 1 Franck Michel
    LoadModule dav_fs_module modules/mod_dav_fs.so
380 1 Franck Michel
    LoadModule dav_lock_module modules/mod_dav_lock.so
381 1 Franck Michel
382 1 Franck Michel
    $ cat /etc/httpd/conf.modules.d/10-subversion.conf 
383 1 Franck Michel
    LoadModule dav_svn_module     modules/mod_dav_svn.so
384 1 Franck Michel
    LoadModule authz_svn_module   modules/mod_authz_svn.so
385 1 Franck Michel
    LoadModule dontdothat_module  modules/mod_dontdothat.so
386 1 Franck Michel
</pre>
387 1 Franck Michel
388 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.
389 1 Franck Michel
390 1 Franck Michel
<pre>
391 1 Franck Michel
    # Enable SVN access from outside Redmine (web browser, SVN client)
392 1 Franck Michel
    <Location /svn>
393 1 Franck Michel
        DAV svn
394 1 Franck Michel
        SVNParentPath "/var/lib/svn"
395 1 Franck Michel
        SVNReposName "Subversion Repository" 
396 1 Franck Michel
        Require all denied
397 1 Franck Michel
398 1 Franck Michel
        # Uncomment the following line when using subversion 1.8 or newer
399 1 Franck Michel
        # (see http://subversion.apache.org/docs/release-notes/1.8.html#serf-skelta-default)
400 1 Franck Michel
        # SVNAllowBulkUpdates Prefer
401 1 Franck Michel
402 1 Franck Michel
        # If a client tries to svn update which involves updating many files,
403 1 Franck Michel
        # the update request might result in an error Server sent unexpected
404 1 Franck Michel
        # return value (413 Request Entity Too Large) in response to REPORT
405 1 Franck Michel
        # request, because the size of the update request exceeds the limit
406 1 Franck Michel
        # allowed by the server. You can avoid this error by disabling the
407 1 Franck Michel
        # request size limit by adding the line LimitXMLRequestBody 0
408 1 Franck Michel
        LimitXMLRequestBody 0
409 1 Franck Michel
410 1 Franck Michel
        # Only check Authentication for root path, nor again for recursive folder.
411 1 Franck Michel
        # Redmine core does only permit access on repository level, so this
412 1 Franck Michel
        # doesn't hurt security. On the other hand it does boost performance a lot!
413 1 Franck Michel
        SVNPathAuthz off
414 1 Franck Michel
415 1 Franck Michel
        PerlAccessHandler Apache::Authn::Redmine::access_handler
416 1 Franck Michel
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
417 1 Franck Michel
        AuthType Basic
418 1 Franck Michel
        AuthName "Redmine SVN Repository" 
419 1 Franck Michel
        AuthUserFile /dev/null
420 1 Franck Michel
421 1 Franck Michel
        # Read-only access    
422 1 Franck Michel
        <Limit GET PROPFIND OPTIONS REPORT>
423 1 Franck Michel
            # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2)
424 1 Franck Michel
            <RequireAny>
425 1 Franck Michel
                Require valid-user
426 1 Franck Michel
                Require local
427 1 Franck Michel
            </RequireAny>
428 1 Franck Michel
        </Limit>
429 1 Franck Michel
430 1 Franck Michel
        # Write access (methods POST, PUT)
431 1 Franck Michel
        <LimitExcept GET PROPFIND OPTIONS REPORT>
432 1 Franck Michel
            Require valid-user
433 1 Franck Michel
        </LimitExcept>
434 1 Franck Michel
435 1 Franck Michel
        # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server
436 1 Franck Michel
        RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>"
437 1 Franck Michel
        RedmineDbUser "redmine" 
438 1 Franck Michel
        RedmineDbPass "<password>" 
439 1 Franck Michel
    </Location>
440 1 Franck Michel
</pre>
441 1 Franck Michel
442 1 Franck Michel
h2. Git integration
443 1 Franck Michel
444 1 Franck Michel
Create the directory where all GIT repos will/have to be stored:
445 1 Franck Michel
<pre>
446 1 Franck Michel
[As root/sudo]:
447 1 Franck Michel
    export GIT=/var/lib/git
448 1 Franck Michel
    mkdir $GIT
449 1 Franck Michel
    chown apache:apache $GIT
450 1 Franck Michel
    chmod 0750 $GIT
451 1 Franck Michel
</pre>
452 1 Franck Michel
453 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 ...".
454 1 Franck Michel
455 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:
456 1 Franck Michel
457 1 Franck Michel
<pre>
458 1 Franck Michel
[As root/sudo]:
459 1 Franck Michel
    # Create a local bare repo
460 1 Franck Michel
    mkdir -p $GIT/test.git
461 1 Franck Michel
    chown apache:apache $GIT/test.git/
462 1 Franck Michel
    cd $GIT/test.git/
463 1 Franck Michel
    git init --bare
464 1 Franck Michel
465 1 Franck Michel
    # Create another repo as a clone of the previous one, make one commit and push.
466 1 Franck Michel
    cd ..
467 1 Franck Michel
    mkdir -p $GIT/test.local.git
468 1 Franck Michel
    cd $GIT/test.local.git/
469 1 Franck Michel
    git init
470 1 Franck Michel
    touch TEST.txt
471 1 Franck Michel
    git add TEST.txt
472 1 Franck Michel
    git commit -m "repository initalization" 
473 1 Franck Michel
    git push $GIT/test.git/ master
474 1 Franck Michel
</pre>
475 1 Franck Michel
476 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.
477 1 Franck Michel
478 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.
479 1 Franck Michel
480 1 Franck Michel
<pre>
481 1 Franck Michel
    #--- Enable Git access from outside Redmine
482 1 Franck Michel
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
483 1 Franck Michel
    
484 1 Franck Michel
    SetEnv GIT_PROJECT_ROOT /var/lib/git
485 1 Franck Michel
    SetEnv GIT_HTTP_EXPORT_ALL
486 1 Franck Michel
487 1 Franck Michel
    <Location /git>
488 1 Franck Michel
        SSLRequireSSL
489 1 Franck Michel
        PerlAccessHandler Apache::Authn::Redmine::access_handler
490 1 Franck Michel
        PerlAuthenHandler Apache::Authn::Redmine::authen_handler
491 1 Franck Michel
        AuthType Basic
492 1 Franck Michel
        AuthName "Redmine Git Repository" 
493 1 Franck Michel
        AuthUserFile /dev/null
494 1 Franck Michel
        Require all denied
495 1 Franck Michel
        
496 1 Franck Michel
        <Limit GET PROPFIND OPTIONS REPORT>
497 1 Franck Michel
            Options Indexes FollowSymLinks MultiViews
498 1 Franck Michel
            # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2)
499 1 Franck Michel
            <RequireAny>
500 1 Franck Michel
                Require valid-user
501 1 Franck Michel
                Require local
502 1 Franck Michel
            </RequireAny>
503 1 Franck Michel
        </Limit>
504 1 Franck Michel
505 1 Franck Michel
        # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server
506 1 Franck Michel
        RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>"
507 1 Franck Michel
        RedmineDbUser "redmine" 
508 1 Franck Michel
        RedmineDbPass "<password>"
509 1 Franck Michel
        RedmineGitSmartHttp yes
510 1 Franck Michel
    </Location>
511 1 Franck Michel
</pre>