Project

General

Profile

Install Redmine 346 on Centos 75 » History » Version 2

Franck Michel, 2018-10-01 22:43
minor changes

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