Project

General

Profile

Install Redmine 346 on Centos 75 » History » Revision 9

Revision 8 (Franck Michel, 2018-10-02 15:06) → Revision 9/14 (Franck Michel, 2018-10-03 13:32)

h1. Installation of Redmine 3.4.6 on CentOS 7.5 + MySQL 8, Apache 2.4, GIT, SVN, LDAP 

 {{>toc}}  

 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. 

 The procedure results of a mix of many different sources for which I give the source URLs in text below. 

 Basics like installing CentOS, Apache, or configuring a certificate for Apache are not covered. 

 Here is the full configuration I got after this installation: 
 * CentOS Linux release 7.5.1804 (Core)  
 * Apache 2.4 (this is important as there were quite some configuration syntax changes since 2.2) 
 * MySQL 8.0 
 * Redmine 3.4.6 
 * Ruby 2.4.4 
 * Apache Passenger 5.3.4 
 * Integration with Git and Svn 
 * Integration with LDAP 

 **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. 


 h2. Install MySQL 8  

 Adapted from "this page":https://www.if-not-true-then-false.com/2010/install-mysql-on-fedora-centos-red-hat-rhel/. 

 h3. Why MySQL 8? 

 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.  

 <pre> 
 [As root/sudo]: 
   yum update -y 
   yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm 
   yum --disablerepo=mysql80-community install mysql-community-server mysql-devel 
   systemctl start mysqld.service 
   systemctl enable mysqld.service 
 </pre> 

 If you prefer to stick to MySQL 5.7, replace the yum install line as follows: 
 <pre> 
   yum --disablerepo=mysql80-community --enablerepo=mysql57-community install mysql-community-server mysql-devel 
 </pre> 


 Get the password created at installation and run the secure procedure 
 <pre> 
   grep 'A temporary password is generated for root@localhost' /var/log/mysqld.log | tail -1 
   /usr/bin/mysql_secure_installation 
 </pre> 

 h3. Bind-address 

 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@). 

 h3. Default password policy 

 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: 
 <pre> 
   default-authentication-plugin=mysql_native_password 
 </pre> 


 h2. Install Ruby 2.4 

 Adapted from "this page":https://tecadmin.net/install-ruby-previous-stable-centos/. 

 <pre> 
 [As root/sudo]: 
   yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel \ 
        libyaml-devel libffi-devel openssl-devel make \ 
        bzip2 autoconf automake libtool bison iconv-devel sqlite-devel 
   curl -sSL https://rvm.io/mpapis.asc | gpg --import - 
   curl -L get.rvm.io | bash -s stable 
   source /etc/profile.d/rvm.sh 
   rvm reload 
   rvm requirements run 
   rvm install 2.4 
   rvm list 
   ruby --version 
 </pre> 
    
 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: 
 <pre> 
   export GEMS=/usr/local/rvm/gems/ruby-2.4.4/gems 
 </pre> 


 h2. Install Redmine 

 Adapted from "this page":https://www.redmine.org/projects/redmine/wiki/RedmineInstall. 

 Below, Redmine is installed in directory /home/username/ 

 h3. Download and untar Redmine, install Ruby packages: 

 <pre> 
 [As non-root]: 
   cd /home/username 
   wget https://www.redmine.org/releases/redmine-3.4.6.tar.gz 
   tar xvfz redmine-3.4.6.tar.gz 
   export REDMINE=/home/username/redmine-3.4.6 
   cd $REDMINE 
   cp config/database.yml.example config/database.yml 
 </pre> 

 Customize $REDMINE/config/database.yml as explained in the "procedure":https://www.redmine.org/projects/redmine/wiki/RedmineInstall#Step-3-Database-connection-configuration. 

 Install GEMS dependencies: 
 <pre> 
 [As root/sudo]: 
   cd $REDMINE 
   gem install bundler 
   bundle install --without development test 
   bundle exec rake generate_secret_token 
   RAILS_ENV=production REDMINE_LANG=en bundle exec rake redmine:load_default_data 
 </pre> 

 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): 
 <pre> 
 [As root/sudo]: 
   cd $REDMINE 
   bundle exec rails server webrick -e production 
 </pre> 
 and browse to http://localhost:3000/. Alternatively, this other command should work exactly the same: 
 <pre> 
 [As root/sudo]: 
   ruby bin/rails server webrick -e production 
 </pre> 

 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. 


 h3. Install Apache Passenger (an Apache plugin for Ruby environments) 

 Adapted from "this page":https://www.vincentliefooghe.net/content/utilisation-apache-passenger-pour-redmine. 
 <pre> 
 [As root/sudo]: 
   yum install -y httpd-devel libcurl-devel apr-devel apr-util-devel mod_ssl 
   cd $REDMINE 
   gem install passenger 
 </pre> 

 Find out the installation path of Passenger, and call the Apache module installer, e.g. in my case: 
 <pre> 
   $GEMS/passenger-5.3.4/bin/passenger-install-apache2-module 
 </pre> 

 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: 
 <pre> 
   LoadModule passenger_module /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4/buildout/apache2/mod_passenger.so 
   <IfModule mod_passenger.c> 
     PassengerRoot /usr/local/rvm/gems/ruby-2.4.4/gems/passenger-5.3.4 
     PassengerDefaultRuby /usr/local/rvm/gems/ruby-2.4.4/wrappers/ruby 
   </IfModule> 
 </pre> 

 h3. Configure Apache as the front end for Redmine 

 *IMPORTANT NOTE*: 
 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. 

 As root, create a virtual host entry in /etc/httpd/conf.d/redmine.conf (adapt the paths to your installation): 
 <pre> 
     <VirtualHost *:80> 
         ServerName youserver.domain.org 
         DocumentRoot "/home/username/redmine-3.4.6/public" 
        
         ErrorLog logs/redmine_error_log 
         LogLevel warn 

         <Directory "/home/username/redmine-3.4.6/public"> 
             Options Indexes ExecCGI FollowSymLinks 
             Require all granted 
             AllowOverride all 
         </Directory> 
     </VirtualHost> 
 </pre> 

 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. 
 <pre> 
   cd $REDMINE 
   chown -R apache:apache files log tmp vendor 
 </pre> 
 Restart apache: 
 <pre> 
   systemctl restart httpd 
 </pre> 
 There you go: browse to http://youserver.domain.org, you should get the login page. Hurah! 
 Login with default login "admin" and password "admin", and of course, change the admin password immediatly. 


 h3. Email config with sendmail 

 As non-root, edit @$REDMINE/config/configuration.yml@ and uncomment the 2 lines concerning sendmail: 
 <pre> 
     email_delivery: 
       delivery_method:sendmail 
 </pre> 

 And install sendmail if it is not yet installed: 
 <pre> 
 [As root/sudo]: 
   yum install -y sendmail sendmail-cf 
 </pre> 

 h3. LDAP authentication 

 Ask the LDAP details to your administrator and set them in the Web interface: Admin > LDAP authentication 

 

 h2. SCM Repos integration - Preliminary 

 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. 

 The reposman.rb script needs @activeresource@ to work, run this (if this is already installed, this will just do nothing): 
 <pre> 
 [As root]: 
     cd $REDMINE 
     gem install activeresource 
 </pre> 
    
 To restrict the access to the WS, secure the Apache configuration by adding this to the  
 VirtualHost configuration (/etc/httpd/conf.d/redmine.conf above). Reminder: this is an Apache 2.4 syntax. 
 <pre> 
    <Location /sys> 
       Require host youserver.domain.org sparks-vm5.i3s.unice.fr localhost 
       Require all denied 
    </Location> 
 </pre> 

 Install Apache packages needed to use the database for authentication (with Git as well as Svn): 
 <pre> 
 [As root/sudo]: 
     yum install -y mod_perl perl-DBI perl-DBD-MySQL perl-Digest-SHA1 perl-LDAP 
 </pre> 

 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". 

 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/. 
 <pre> 
 [As root/sudo]: 
     mkdir /usr/lib64/perl5/vendor_perl/Apache/Authn 
     ln -s $REDMINE/extra/svn/Redmine.pm /usr/lib64/perl5/vendor_perl/Authn/Apache 
 </pre> 

 Optional: to allow for LDAP authentication, install the Simple LDAP modules with CPAN. In my cases, it required dependencies Modules::Build and Params::Validate: 
 <pre> 
 [As root/sudo]: 
     cpan 
     install Modules::Build 
     install Params::Validate 
     install Authen::Simple::LDAP 
 </pre> 

 Update the Apache Redmine configuration (redmine.conf) as shown below: 
 <pre> 
     PerlLoadModule Apache::Authn::Redmine 
     PerlLoadModule Redmine 

     # Enable connection pooling (useful for checkouts with many files) 
     PerlModule DBI 
     PerlOptions +GlobalRequest 

     # Enable LDAP(S) authentication (optional) 
     PerlLoadModule Authen::Simple::LDAP 
     PerlLoadModule IO::Socket::SSL 
 </pre> 

 *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: 
 <pre> 
     Can't call method "prepare" on an undefined value at /usr/lib64/perl5/vendor_perl/Apache/Redmine.pm line 364, <DATA> line 747.\n 
 </pre> 
 A closer look at the regular Apache error_log shows another error: 
 <pre> 
     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. 
 </pre> 

 To fix this, change MySQL's password policy for user redmine (found "here":https://my.oschina.net/johnsken/blog/1840348): 
 <pre> 
     mysql -uroot -p 
     mysql> show variables like 'default_authentication_plugin'; 
     +-------------------------------+-----------------------+ 
     | Variable_name                   | Value                   | 
     +-------------------------------+-----------------------+ 
     | default_authentication_plugin | caching_sha2_password | 
     +-------------------------------+-----------------------+ 

     mysql> select host,user,plugin from mysql.user; 
     +-----------+------------------+-----------------------+ 
     | host        | user               | plugin                  | 
     +-----------+------------------+-----------------------+ 
     | localhost | mysql.infoschema | caching_sha2_password | 
     | localhost | mysql.session      | caching_sha2_password | 
     | localhost | mysql.sys          | caching_sha2_password | 
     | localhost | redmine            | caching_sha2_password | 
     | localhost | root               | caching_sha2_password | 
     +-----------+------------------+-----------------------+ 

     mysql> ALTER USER 'redmine'@'localhost' IDENTIFIED WITH mysql_native_password BY '<YOUR REDMINE PASSWORD>'; 
     Query OK, 0 rows affected (0,10 sec) 

     mysql> select host,user,plugin from mysql.user; 
     +-----------+------------------+-----------------------+ 
     | host        | user               | plugin                  | 
     +-----------+------------------+-----------------------+ 
     | localhost | mysql.infoschema | caching_sha2_password | 
     | localhost | mysql.session      | caching_sha2_password | 
     | localhost | mysql.sys          | caching_sha2_password | 
     | localhost | redmine            | mysql_native_password | 
     | localhost | root               | caching_sha2_password | 
     +-----------+------------------+-----------------------+ 
 </pre> 

 

 h2. SVN integration 

 

 h3. Repositories access control with Apache 2.4 with mod_dav_svn and mod_perl 

 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". 

 Make sure SVN CLI packages are already installed. 
 <pre> 
     yum -y install svn 
 </pre> 

 Create the directory where all SVN repos will/have to be stored: 
 <pre> 
 [As root/sudo]: 
     export SVN=/var/lib/svn 
     mkdir $SVN 
     chown apache:apache $SVN 
     chmod 0750 $SVN 
 </pre> 

 Then, there are two options to attach an SVN repository to a project: 

 _1. Explicitly attach a repo to a project_ 

 Copy an existing repository to $SVN, or create an new empty repository, and change its owner, like this: 
 <pre> 
     svnadmin create $SVN/<repo_name> 
     chown -R apache:apache $SVN/<repo_name> 
 </pre> 

 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. 


 _2. Automatically create SVN repos for declared projects_ 
 You can also ask Redmine to automatically create SVN repos for each declared project: the new repo will be name after the project name. 

 <pre> 
 [As root/sudo]: 
     cd $REDMINE/extra/svn 
     ruby reposman.rb --redmine https://youserver.domain.org --svn-dir $SVN \ 
                      --owner apache --url http://youserver.domain.org/svn/ \ 
                      --verbose --key=<ws_key> 
 </pre> 

 In my case, I had declared a single test project, here is the result: 
 <pre> 
     querying Redmine for active projects with repository module enabled... 
     retrieved    projects 
     processing project test (test) 
         repository /var/lib/svn/test created 
         repository /var/lib/svn/test registered in Redmine with url http://youserver.domain.org/svn/test 
 </pre> 

 

 h3. SVN access from Apache 

 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). 

 Install Apache needed packages:  
 <pre> 
 [As root/sudo]: 
     yum install -y mod_dav_svn 
 </pre> 

 The installation should add loading of DAV and SVN modules to the Apache configuration. Check and fix this if necessary: 
 <pre> 
     $ cat /etc/httpd/conf.modules.d/00-dav.conf  
     LoadModule dav_module modules/mod_dav.so 
     LoadModule dav_fs_module modules/mod_dav_fs.so 
     LoadModule dav_lock_module modules/mod_dav_lock.so 

     $ cat /etc/httpd/conf.modules.d/10-subversion.conf  
     LoadModule dav_svn_module       modules/mod_dav_svn.so 
     LoadModule authz_svn_module     modules/mod_authz_svn.so 
     LoadModule dontdothat_module    modules/mod_dontdothat.so 
 </pre> 

 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. 

 <pre> 
     # Enable SVN access from outside Redmine (web browser, SVN client) 
     <Location /svn> 
         DAV svn 
         SVNParentPath "/var/lib/svn" 
         SVNReposName "Subversion Repository"  
         Require all denied 

         # Uncomment the following line when using subversion 1.8 or newer 
         # (see http://subversion.apache.org/docs/release-notes/1.8.html#serf-skelta-default) 
         # SVNAllowBulkUpdates Prefer 

         # If a client tries to svn update which involves updating many files, 
         # the update request might result in an error Server sent unexpected 
         # return value (413 Request Entity Too Large) in response to REPORT 
         # request, because the size of the update request exceeds the limit 
         # allowed by the server. You can avoid this error by disabling the 
         # request size limit by adding the line LimitXMLRequestBody 0 
         LimitXMLRequestBody 0 

         # Only check Authentication for root path, nor again for recursive folder. 
         # Redmine core does only permit access on repository level, so this 
         # doesn't hurt security. On the other hand it does boost performance a lot! 
         SVNPathAuthz off 

         PerlAccessHandler Apache::Authn::Redmine::access_handler 
         PerlAuthenHandler Apache::Authn::Redmine::authen_handler 
         AuthType Basic 
         AuthName "Redmine SVN Repository"  
         AuthUserFile /dev/null 

         # Read-only access     
         <Limit GET PROPFIND OPTIONS REPORT> 
             # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2) 
             <RequireAny> 
                 Require valid-user 
                 Require local 
             </RequireAny> 
         </Limit> 

         # Write access (methods POST, PUT) 
         <LimitExcept GET PROPFIND OPTIONS REPORT> 
             Require valid-user 
         </LimitExcept> 

         # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server 
         RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>" 
         RedmineDbUser "redmine"  
         RedmineDbPass "<password>"  
     </Location> 
 </pre> 

 

 h2. Git integration 

 Create the directory where all GIT repos will/have to be stored: 
 <pre> 
 [As root/sudo]: 
     export GIT=/var/lib/git 
     mkdir $GIT 
     chown apache:apache $GIT 
     chmod 0750 $GIT 
 </pre> 

 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 ...". 

 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: 

 <pre> 
 [As root/sudo]: 
     # Create a local bare repo 
     mkdir -p $GIT/test.git 
     chown apache:apache $GIT/test.git/ 
     cd $GIT/test.git/ 
     git init --bare 

     # Create another repo as a clone of the previous one, make one commit and push. 
     cd .. 
     mkdir -p $GIT/test.local.git 
     cd $GIT/test.local.git/ 
     git init 
     touch TEST.txt 
     git add TEST.txt 
     git commit -m "repository initalization"  
     git push $GIT/test.git/ master 
 </pre> 

 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. 

 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. 

 <pre> 
     #--- Enable Git access from outside Redmine 
     ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ 
    
     SetEnv GIT_PROJECT_ROOT /var/lib/git 
     SetEnv GIT_HTTP_EXPORT_ALL 

     <Location /git> 
         SSLRequireSSL 
         PerlAccessHandler Apache::Authn::Redmine::access_handler 
         PerlAuthenHandler Apache::Authn::Redmine::authen_handler 
         AuthType Basic 
         AuthName "Redmine Git Repository"  
         AuthUserFile /dev/null 
         Require all denied 
        
         <Limit GET PROPFIND OPTIONS REPORT> 
             Options Indexes FollowSymLinks MultiViews 
             # Match either the valid user or local source conditions (equivalent to "Satisfy any" in Apache 2.2) 
             <RequireAny> 
                 Require valid-user 
                 Require local 
             </RequireAny> 
         </Limit> 

         # Mysql config. You may use localhost instead of <your.mysql.hostname> if MySQL is on the same server 
         RedmineDSN "DBI:mysql:database=redmine;host=<your.mysql.hostname>" 
         RedmineDbUser "redmine"  
         RedmineDbPass "<password>" 
         RedmineGitSmartHttp yes 
     </Location> 
 </pre>