Install Redmine 346 on Centos 75 » History » Version 9

Franck Michel, 2018-10-03 13:32
Apache 2.2 vs. 2.4 warning

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