Install Redmine 346 on Centos 75 » History » Revision 13
Revision 12 (Franck Michel, 2018-11-19 13:59) → Revision 13/14 (Franck Michel, 2019-01-09 15:27)
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 * MySQL 8.0 * Redmine 3.4.6 * Ruby 2.4.4 * Apache Passenger 5.3.4 * Integration with Git and Svn * Integration with LDAP *IMPORTANT NOTE*: This installation uses **Apache 2.4** in which there are quite some configuration syntax changes compared to 2.2. Directives Allow, Deny, Order are obsolete as of Apache 2.4, but you can still use them for compatibility reasons. However, mixing the new Require directives with the former ones has unexpected results. So, *do not blindly copy/paste examples you shall find on the Web*, most of them are deprecated and will screw your configuration! See "details":https://httpd.apache.org/docs/2.4/en/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 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 clone --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 chown -R apache:apache $GIT/test.git/ # 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>