Redmine avec Thin
Redmine est une application web codée en Ruby. Pour l’exécuter nous devons passer par un serveur d’application web.
Nous allons aborder l’installation du serveur d’application thin.
Introduction
Parmi les serveurs d’application ruby, il existe au moins Unicorn, Mongrel et Thin. Je n’ai pas trouvé de comparatif récent. Au vu des lectures, je me contenterai de noter que Thin fait correctement son boulot et est peu gourmand en ressources.
Si nous sommes sur un serveur dédié aux applications web codé en ruby, nous pourrions nous contenter de Thin et d’écouter sur le port 80. Dans ce cas il n’est ni necessaire de penser à Nginx, Apache ou autre serveur web, ni de lire au delà du prochain chapitre.
À défaut d’un serveur d’application dédié, il est possible aussi d’utiliser un serveur web classique et de passer par un module pour gérer les applications ruby, par exemple avec passenger.
Enfin il est possible de configurer un serveur web pour qu’il délègue le travail au serveur d’application ruby lorsque cela est necessaire. C’est ce cas de figure que nous abordons ici.
Prérequis
Pour la suite de l’article, nous considérons un serveur Debian à jour avec le paquet Redmine installé et fonctionnel.
Par la suite nous verrons la configuration de base pour interfacer Apache et Nginx avec Thin.
Installation de Thin
Thin est présent par défaut dans les dépôts officiels de Debian, nous l’installons :
apt-get install thin
Il est possible d’avoir une version plus récente soit en passant par un dépôt de type backport, soit en l’installant en tant que Gem, ces 2 cas de figure ne sont pas abordés ici.
Configuration de Thin
La configuration de Thin se passe dans /etc/thin/. Thin au démarrage chargera l’ensemble des fichiers Yaml présents.
Une configuration classique pour Redmine prend cette forme :
pid: /var/run/thin/redmine.pid
group: www-data
timeout: 30
log: /var/log/thin/redmine.log
max_conns: 1024
require: [/etc/thin/redmine.rb]
max_persistent_conns: 512
environment: production
user: www-data
servers: 4
daemonize: true
chdir: /usr/share/redmine
port: 5000
address: 0.0.0.0
Les points à noter :
- l’écoute en TCP sur toutes IP du serveur address : 0.0.0.0
- l’écoute des ports 5000 à 5003 port : 5000 et servers : 4
Thin pourra être sollicité par 4 requêtes simultanées.
La spécificité de la version Debian réside dans la déclaration d’une variable spécifique X_DEBIAN_SITEID spécifiant l’instance à exécuter.
Cet appel se fait grâce à require : [/etc/thin/redmine.rb],
ENV['X_DEBIAN_SITEID'] = 'default'
Le paquet Redmine de Debian permet de mutualiser le code Ruby et de charger la configuration spécifique à une instance via cette propriété. Les instances Redmine sont stockées dans /etc/redmine/instances et sont configurables via dpkg-reconfigure redmine
Passer par Apache
Pour déléguer le travail à Thin depuis Apache, nous profitons des modules proxy natifs.
a2enmod proxy_balancer
Une configuration type donne ceci :
<Proxy balancer://thinservers>
BalancerMember http://192.168.0.10:5000 route=thin0
BalancerMember http://192.168.0.10:5001 route=thin1
BalancerMember http://192.168.0.10:5002 route=thin2
BalancerMember http://192.168.0.10:5003 route=thin3
</Proxy>
ProxyPass / balancer://thinservers/
ProxyPassReverse / balancer://thinservers/
ProxyPreserveHost on
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
On profite du mode balancer pour repartir les requetes surles 4 ports en écoute de Thin.
Dans l’exemple, on notera que Thin répondra depuis l’IP 192.168.0.10 .
Thin et Apache peuvent être aussi bien installés sur le même serveur physique que sur 2 serveurs distincts.
Passer par Nginx
upstream redmine_thin_servers {
server 192.168.0.10:5000;
server 192.168.0.10:5001;
server 192.168.0.10:5002;
server 192.168.0.10:5003;
}
server {
location @redmine_thin_servers {
proxy_pass http://redmine_thin_servers;
}
}
La configuration se veut équivalente à celle montrée avec Apache.
Si nous avions Nginx et Thin sur le même serveur nous pourrions préférer les sockets Unix à TCP. Ceci fera peut être l’objet d’un autre article.
Conclusion
Avec ces éléments, il est possible d’exécuter une instance Redmine ou tout autre application Ruby via un serveur d’application dédié.
Je trouve que passer par Thin ou un de ses homologues est plus intéressant que de passer par un module, il est plus facile d’isoler les services entre eux et de mieux dimensionner les ressources physiques dans le temps.