Cómo instalar Redmine en CentOS 8

En esta entrada vamos a ver cómo instalar Redmine en CentOS 8 paso a paso, de manera que al final de este artículo podrás empezar a trabajar con este administrador de proyectos desde tu servidor o VPS CentOS. La instalación no es un proceso trivial, pero en esta guía te detallaremos todos los pasos necesarios para llegar a la meta con éxito.

Antes de instalar Redmine en CentOS 8

Si quieres seguir los pasos de esta guía de instalación de Redmine en CentOS 8 debes satisfacer los siguientes requisitos básicos:

Si no dispones aún del entorno necesario sin duda te servirán nuestras guías de instalación del servicio web en CentOS 8, de MariaDB en CentOS 8, de PostgreSQL en CentOS 8, de PostgreSQL en CentOS 8 y del repositorio EPEL en CentOS 8.

También necesitaremos algunas herramientas que podemos obtener desde los repositorios de CentOS 8, por lo que actualizamos las listas de paquetes:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum update
~$ sudo yum update
~$ sudo yum update

E instalamos las herramientas necesarias:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y policycoreutils-python-utils tar wget
~$ sudo yum install -y policycoreutils-python-utils tar wget
~$ sudo yum install -y policycoreutils-python-utils tar wget

Cómo descargar Redmine para CentOS 8

Vamos a descargar Redmine para CentOS 8 desde la sección de descargas del sitio web oficial, donde encontraremos la última versión estable:

como descargar redmine para centos 8 / centos stream 8

Encontraremos el paquete de Redmine en formatos .tar.gz y .zip. Aunque podemos realizar la descarga directamente desde el navegador, en este tutorial copiaremos el enlace del paquete .tar.gz para descargar desde consola con el comando wget (ideal en caso de trabajar en remoto):

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ wget https://www.redmine.org/releases/redmine-5.0.1.tar.gz
~$ wget https://www.redmine.org/releases/redmine-5.0.1.tar.gz
~$ wget https://www.redmine.org/releases/redmine-5.0.1.tar.gz

Cómo instalar Redmine en CentOS 8

El proceso de instalar Redmine en CentOS 8 es bastante laborioso y no está exento de problemas, es fácil quedarse estancado si no se cuenta con una guía exhaustiva, como la presente. A continuación veremos los pasos necesarios para hacer funcionar esta aplicación.

Archivos de Redmine

Creamos un directorio para Redmine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo mkdir /opt/redmine
~$ sudo mkdir /opt/redmine
~$ sudo mkdir /opt/redmine

Y descomprimimos el paquete que acabamos de descargar:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo tar xf redmine-5.0.1.tar.gz -C /opt/redmine/
~$ sudo tar xf redmine-5.0.1.tar.gz -C /opt/redmine/
~$ sudo tar xf redmine-5.0.1.tar.gz -C /opt/redmine/

Como el subdirectorio que se acaba de crear contiene números de versión en su nombre lo renombraremos de forma más simple para facilitar el proceso de instalación, configuración y mantenimiento:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo mv /opt/redmine/redmine-5.0.1/ /opt/redmine/redmine
~$ sudo mv /opt/redmine/redmine-5.0.1/ /opt/redmine/redmine
~$ sudo mv /opt/redmine/redmine-5.0.1/ /opt/redmine/redmine

Instalar los pre-requisitos

Instalamos ciertas dependencias para la aplicación y el servicio web:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y gcc make patch redhat-rpm-config ruby-devel rubygem-bundler zlib-devel mod_passenger passenger-devel
~$ sudo yum install -y gcc make patch redhat-rpm-config ruby-devel rubygem-bundler zlib-devel mod_passenger passenger-devel
~$ sudo yum install -y gcc make patch redhat-rpm-config ruby-devel rubygem-bundler zlib-devel mod_passenger passenger-devel

Dependencias según el servicio de bases de datos

En el caso de tener instalado MariaDB instalaremos además la biblioteca de desarrollo:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y mariadb-devel
~$ sudo yum install -y mariadb-devel
~$ sudo yum install -y mariadb-devel

Si se trata de MySQL:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y mysql-devel
~$ sudo yum install -y mysql-devel
~$ sudo yum install -y mysql-devel

En cuanto a PostgreSQL, si se trata de la versión nativa de la distribución:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y libpq-devel
~$ sudo yum install -y libpq-devel
~$ sudo yum install -y libpq-devel

Pero si procede del repositorio oficial de PostgreSQL:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo yum install -y libpq5-devel
~$ sudo yum install -y libpq5-devel
~$ sudo yum install -y libpq5-devel

Servicio de bases de datos

En este paso prepararemos el servicio de bases de datos sobre sobre el que trabajará Redmine, teniendo en cuenta los más populares en CentOS 8.

MariaDB/MySQL

Conectamos con el cliente mysql y un usuario administrador:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ mysql -u root -p
~$ mysql -u root -p
~$ mysql -u root -p

Creamos la base de datos:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> create database redmine charset utf8mb4 collate utf8mb4_unicode_ci;
> create database redmine charset utf8mb4 collate utf8mb4_unicode_ci;
> create database redmine charset utf8mb4 collate utf8mb4_unicode_ci;

Creamos el usuario:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> create user redmine@localhost identified by 'XXXXXXXX';
> create user redmine@localhost identified by 'XXXXXXXX';
> create user redmine@localhost identified by 'XXXXXXXX';

Damos los permisos necesarios al usuario sobre la base:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> grant all privileges on redmine.* to redmine@localhost;
> grant all privileges on redmine.* to redmine@localhost;
> grant all privileges on redmine.* to redmine@localhost;

Y cerramos la sesión:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
> exit
> exit
> exit

PostgreSQL

Iniciamos sesión con el cliente psql y el usuario postgres:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo -iu postgres psql
~$ sudo -iu postgres psql
~$ sudo -iu postgres psql

Creamos un rol con contraseña:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# create role redmine login encrypted password 'XXXXXXXX' noinherit valid until 'infinity';
# create role redmine login encrypted password 'XXXXXXXX' noinherit valid until 'infinity';
# create role redmine login encrypted password 'XXXXXXXX' noinherit valid until 'infinity';

Creamos la base de datos:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# create database redmine with encoding='utf8' owner='redmine';
# create database redmine with encoding='utf8' owner='redmine';
# create database redmine with encoding='utf8' owner='redmine';

Y cerramos la conexión:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# \q
# \q
# \q

Instalación de Redmine

Cambiamos el directorio de trabajo al nuevo subdirectorio de Redmine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ cd /opt/redmine/redmine/
~$ cd /opt/redmine/redmine/
~$ cd /opt/redmine/redmine/

Creamos el archivo de configuración de bases de datos para Redmine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ nano config/database.yml
$ nano config/database.yml
$ nano config/database.yml

Si trabajamos con MariaDB/MySQL el contenido será el siguiente:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
production:
adapter: mysql2
database: redmine
host: localhost
username: redmine
password: "XXXXXXXX"
# Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
encoding: utf8mb4
production: adapter: mysql2 database: redmine host: localhost username: redmine password: "XXXXXXXX" # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7 encoding: utf8mb4
production:
  adapter: mysql2
  database: redmine
  host: localhost
  username: redmine
  password: "XXXXXXXX"
  # Use "utf8" instead of "utfmb4" for MySQL prior to 5.7.7
  encoding: utf8mb4

Mientras que si se trata de PostgreSQL será este otro:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
production:
adapter: postgresql
database: redmine
host: localhost
username: redmine
password: "XXXXXXXX"
encoding: utf8
production: adapter: postgresql database: redmine host: localhost username: redmine password: "XXXXXXXX" encoding: utf8
production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: redmine
  password: "XXXXXXXX"
  encoding: utf8

Las variables database, username y password deben contener los valores que usaste anteriormente en la preparación del servicio de bases de datos.

Guardamos los cambios y cerramos el archivo.

Compilación

Editamos el archivo Gemfile:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ nano Gemfile
$ nano Gemfile
$ nano Gemfile

En este archivo hay algunas líneas relativas a sistemas Windows que provocarán avisos al realizar la instalación:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
...
gem "ffi", platforms: [:mingw, :x64_mingw, :mswin]
...
... gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin] ... gem "ffi", platforms: [:mingw, :x64_mingw, :mswin] ...
...
gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
...
  gem "ffi", platforms: [:mingw, :x64_mingw, :mswin]
...

Desactivamos dichas líneas insertando un carácter # al inicio de línea:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
#gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
...
# gem "ffi", platforms: [:mingw, :x64_mingw, :mswin]
...
... #gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin] ... # gem "ffi", platforms: [:mingw, :x64_mingw, :mswin] ...
...
#gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin]
...
#  gem "ffi", platforms: [:mingw, :x64_mingw, :mswin]
...

Guardamos el archivo y comenzamos la compilación.

Independientemente del motor de bases de datos usado, ejecutamos bundle para compilar el grupo principal de gemas:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ bundle install --without development test
$ bundle install --without development test
$ bundle install --without development test

Es posible que durante el proceso se solicite la contraseña del usuario para realizar algunas tareas con sudo.

En el momento de redactar este tutorial algunas gemas no quedan correctamente instaladas tras este proceso, así que las instalamos de nuevo con sudo:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ sudo gem pristine racc nio4r websocket-driver commonmarker digest io-wait strscan redcarpet
$ sudo gem pristine racc nio4r websocket-driver commonmarker digest io-wait strscan redcarpet
$ sudo gem pristine racc nio4r websocket-driver commonmarker digest io-wait strscan redcarpet

Finalmente, si usas MariaDB/MySQL también habrá que hacer lo mismo con la gema correspondiente:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ sudo gem pristine mysql2
$ sudo gem pristine mysql2
$ sudo gem pristine mysql2

Y si usas PostgreSQL, hay que instalar la gema para usar dicha base de datos:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ sudo gem pristine pg
$ sudo gem pristine pg
$ sudo gem pristine pg

Continuamos generando el token para cifrar las cookies del sitio:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ bundle exec rake generate_secret_token
$ bundle exec rake generate_secret_token
$ bundle exec rake generate_secret_token

Si esta operación falla debida a la falta de alguna gema, repite el paso interior para instalar la gema concreta con sudo.

Preparamos la base de datos para Redmine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ RAILS_ENV=production bundle exec rake db:migrate
$ RAILS_ENV=production bundle exec rake db:migrate
$ RAILS_ENV=production bundle exec rake db:migrate

Cargamos los datos iniciales:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ RAILS_ENV=production bundle exec rake redmine:load_default_data
$ RAILS_ENV=production bundle exec rake redmine:load_default_data
$ RAILS_ENV=production bundle exec rake redmine:load_default_data

Nos solicitará el idioma a instalar:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
Select language: ar, az, bg, bs, ca, cs, da, de, el, en, en-GB, es, es-PA, et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en]
... Select language: ar, az, bg, bs, ca, cs, da, de, el, en, en-GB, es, es-PA, et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en]
...
Select language: ar, az, bg, bs, ca, cs, da, de, el, en, en-GB, es, es-PA, et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en]

En este tutorial elegiremos el español, por lo que teclearemos es.

Ya podemos salir de este directorio y regresar a nuestro directorio personal:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$ cd
$ cd
$ cd

Concedemos la propiedad del directorio de Redmine al usuario con el que corre el servicio web:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo chown -R apache: /opt/redmine/redmine/
~$ sudo chown -R apache: /opt/redmine/redmine/
~$ sudo chown -R apache: /opt/redmine/redmine/

Ajustamos los permisos de lectura y escritura:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo chmod -R 755 /opt/redmine/redmine/{files,log,tmp,public/plugin_assets}
~$ sudo chmod -R 755 /opt/redmine/redmine/{files,log,tmp,public/plugin_assets}
~$ sudo chmod -R 755 /opt/redmine/redmine/{files,log,tmp,public/plugin_assets}

Creamos un enlace simbólico:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo ln -s /opt/redmine/redmine/public/ /var/www/html/redmine
~$ sudo ln -s /opt/redmine/redmine/public/ /var/www/html/redmine
~$ sudo ln -s /opt/redmine/redmine/public/ /var/www/html/redmine

Configuración de Apache

Es posible que la configuración por defecto del módulo Passenger de Apache por defecto sea errónea. Obtendremos el valor de la raíz de archivos del módulo con el comando passenger-config:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ passenger-config --root
/usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini
~$ passenger-config --root /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini
~$ passenger-config --root
/usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini

Editamos la configuración del módulo Passenger:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo nano /etc/httpd/conf.d/passenger.conf
~$ sudo nano /etc/httpd/conf.d/passenger.conf
~$ sudo nano /etc/httpd/conf.d/passenger.conf

Y buscamos la directiva PassengerRoot:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini
...
... PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini ...
...
   PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini
...

Podemos comprobar que el valor por defecto difiere del valor del sistema, así que podemos cambiarlo o desactivar la directiva presente y añadir una nueva con el valor correcto:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
# PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini
PassengerRoot /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini
...
... # PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini PassengerRoot /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini ...
...
#   PassengerRoot /usr/share/passenger/phusion_passenger/locations.ini
   PassengerRoot /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini
...

Dentro del mismo bloque IfModule, añadimos la directiva PassengerUser con el valor del usuario con el que corre el servicio web:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
...
PassengerUser apache
...
... PassengerUser apache ...
...
   PassengerUser apache
...

Ya podemos guardar y cerrar este archivo.

Ahora es turno de crear la configuración de Apache para Redmine:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo nano /etc/httpd/conf.d/redmine.conf
~$ sudo nano /etc/httpd/conf.d/redmine.conf
~$ sudo nano /etc/httpd/conf.d/redmine.conf

Con el contenido:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<Directory /var/www/html/redmine>
RailsEnv production
RailsBaseURI /redmine
Options -MultiViews
</Directory>
<Directory /var/www/html/redmine> RailsEnv production RailsBaseURI /redmine Options -MultiViews </Directory>
<Directory /var/www/html/redmine>
        RailsEnv production
        RailsBaseURI /redmine
        Options -MultiViews
</Directory>

Guardamos el archivo y reiniciamos el servicio web:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo systemctl restart httpd
~$ sudo systemctl restart httpd
~$ sudo systemctl restart httpd

Cómo acceder a Redmine en CentOS 8 por primera vez

En caso de usar SELinux, antes de acceder a Redmine en CentOS 8 desde un navegador por primera vez, debemos desactivarlo temporalmente:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo setenforce 0
~$ sudo setenforce 0
~$ sudo setenforce 0

Accedemos a Redmine desde el navegador, añadiendo el alias /redmine a la dirección IP, nombre DNS, dominio, etc. de la máquina CentOS 8.

Por ejemplo, la máquina CentOS 8 sobre la que hemos preparado este artículo es accesible en el subdominio centos8.local.lan, así que accedemos empleando http://centos8.local.lan/redmine como URL:

como instalar redmine en centos 8 / centos stream 8

El primer acceso puede tomar unos instantes. Una vez mostrada la página de inicio, iniciamos sesión mediante el enlace «Iniciar sesión«:

instalar redmine en centos 8 / centos stream 8

Utilizamos el usuario administrador por defecto y su contraseña, que son admin y admin, respectivamente.

Automáticamente Redmine nos obliga a cambiar la contraseña por seguridad:

instalando redmine en centos 8 / centos stream 8

Una vez cambiada la contraseña se nos redirige a la página del perfil del administrador, donde se nos comunica que la contraseña ha sido cambiada con éxito:

redmine para centos 8 / centos stream 8

En este momento, si usas SELinux en tu sistema y lo has desactivado hace unos instantes según lo dicho antes, regresamos a consola y cremos un módulo de política de SELinux para el módulo Passenger de Apache:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo grep httpd /var/log/audit/audit.log | sudo audit2allow -M passenger
~$ sudo grep httpd /var/log/audit/audit.log | sudo audit2allow -M passenger
~$ sudo grep httpd /var/log/audit/audit.log | sudo audit2allow -M passenger

Cargamos esta nueva política desde el archivo que acabamos de crear:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo semodule -i passenger.pp
~$ sudo semodule -i passenger.pp
~$ sudo semodule -i passenger.pp

Se puede borrar el archivo, puesto que no lo neceistaremos más:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo rm passenger.pp
~$ sudo rm passenger.pp
~$ sudo rm passenger.pp

Y ya podemos activar SELinux de nuevo:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
~$ sudo setenforce 1
~$ sudo setenforce 1
~$ sudo setenforce 1

A partir de este momento seguiremos usando la aplicación con normalidad.

Por ejemplo, podríamos visitar el área de administración:

redmine en centos 8 / centos stream 8

¡Todo listo para trabajar y gestionar tus proyectos con Redmine en CentOS 8!

Conclusión

Ahora que sabes cómo instalar Redmine en CentOS 8 ya puedes trabajar con este fantástico gestor de proyectos. Habrás visto que el proceso de instalación dista bastante de ser simple y, créeme, teniendo los pasos ordenados a mano, te ahorras un buen dolor de cabeza gracias a esta guía.

¡Apoya comoinstalar.me!

¿Ya funciona Redmine en tu máquina CentOS 8? Si es así y quieres agradecérmelo, puedes hacerlo dejando 1 $ de propina con PayPal:

O, si te sientes especialmente agradecido, invitándome a un café:

¡Gracias!

Valora esta entrada

5/5 - (4 votos)

3 comentarios en «Cómo instalar Redmine en CentOS 8»

Deja un comentario