403 lines
10 KiB
Markdown
403 lines
10 KiB
Markdown
|
---
|
||
|
title: Discourse sans Docker
|
||
|
slug: 6-discourse-sans-docker
|
||
|
date: "2016-06-27T00:00:00+02:00"
|
||
|
categories:
|
||
|
- DevOps
|
||
|
tags:
|
||
|
- discourse
|
||
|
- docker
|
||
|
summary: >
|
||
|
Instructions détaillées sur la façon d'installer Discourse et ses plugins sans
|
||
|
Docker.
|
||
|
---
|
||
|
|
||
|
{{< warning >}}
|
||
|
La seule méthode officielle est [avec Docker]. Vous pourriez ne pas obtenir de
|
||
|
support de Discourse en suivant cette méthode.
|
||
|
[avec Docker]: http://blog.discourse.org/2014/04/install-discourse-in-under-30-minutes/
|
||
|
{{< /warning >}}
|
||
|
|
||
|
L'équipe derrière [Discourse] a choisi de ne publier que des images Docker de
|
||
|
leur logiciel. La raison derrière cela est : il est plus facile de ne supporter
|
||
|
qu'une seule configuration. Je ne discuterai pas de cela. C'est leur choix.
|
||
|
|
||
|
Cependant, je n'aime pas utiliser Docker pour déployer des applications en
|
||
|
production. Vraiment pas. Si vous êtes comme moi, voici les étapes que
|
||
|
j'ai utilisées pour l'installer et le configurer.
|
||
|
|
||
|
J'utilise des serveurs Debian en production, donc les étapes ci-dessous sont
|
||
|
toutes orientées Debian.
|
||
|
|
||
|
{{< note >}}
|
||
|
Ceci n'est pas destiné à être un guide complet. Beaucoup de commandes et
|
||
|
fichiers de configuration pourraient avoir besoin d'être adaptés à votre
|
||
|
environnement.
|
||
|
|
||
|
Il ne traite même pas de sujets importants en production tels que
|
||
|
la sécurité. Cela est laissé comme exercice au lecteur.
|
||
|
{{< /note >}}
|
||
|
|
||
|
## Installation
|
||
|
|
||
|
Discourse est une application Rails. Elle peut être installée comme
|
||
|
n'importe quelle autre application Rails :
|
||
|
|
||
|
Tout d'abord, Discourse utilise Redis et PostgreSQL (ou du moins,
|
||
|
je préfère utiliser Postgres). J'utilise également Nginx comme proxy pour
|
||
|
l'application. Installez les dépendances externes :
|
||
|
|
||
|
```sh
|
||
|
# Ajoutez le dépôt pour Redis
|
||
|
echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list
|
||
|
wget https://www.dotdeb.org/dotdeb.gpg -O - | apt-key add -
|
||
|
|
||
|
# Ajoutez le dépôt pour PostgreSQL :
|
||
|
echo "deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main" > /etc/apt/sources.list.d/postgresql.list
|
||
|
wget -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||
|
|
||
|
apt-get update
|
||
|
apt-get install postgresql-9.5 redis-server nginx
|
||
|
```
|
||
|
|
||
|
Ensuite, créez une base de données pour l'application. Entrez dans l'interface
|
||
|
de commande de postgres :
|
||
|
|
||
|
```sh
|
||
|
su - postgres -c psql
|
||
|
```
|
||
|
|
||
|
et entrez les commandes suivantes :
|
||
|
|
||
|
```sql
|
||
|
CREATE DATABASE discourse;
|
||
|
CREATE USER discourse;
|
||
|
ALTER USER discourse WITH ENCRYPTED PASSWORD 'password';
|
||
|
ALTER DATABASE discourse OWNER TO discourse;
|
||
|
\connect discourse
|
||
|
CREATE EXTENSION hstore;
|
||
|
CREATE EXTENSION pg_trgm;
|
||
|
```
|
||
|
|
||
|
Ensuite, vous pouvez cloner le code de Discourse :
|
||
|
|
||
|
```sh
|
||
|
git clone https://github.com/discourse/discourse.git /chemin/vers/discourse
|
||
|
#
|
||
|
# Optionnellement, basculez sur une étiquette spécifique
|
||
|
cd /chemin/vers/discourse
|
||
|
git checkout v1.5.3
|
||
|
```
|
||
|
|
||
|
Ensuite, allez dans le répertoire principal de l'application, et configurez-la
|
||
|
comme n'importe quelle application Rails :
|
||
|
|
||
|
```bash
|
||
|
# Optionnellement, configurez rvm avec ruby 1.9.3 minimum (j'utilise 2.3.0)
|
||
|
rvm install 2.3.0
|
||
|
rvm use 2.3.0
|
||
|
|
||
|
# installez les dépendances
|
||
|
cd /chemin/vers/discourse
|
||
|
RAILS_ENV=production bundle install
|
||
|
```
|
||
|
|
||
|
Il est temps de configurer l'application.
|
||
|
|
||
|
Ici, Discourse a une petite particularité : la configuration de production se
|
||
|
trouve dans le fichier `./config/discourse.conf`.
|
||
|
|
||
|
Créez ce fichier :
|
||
|
|
||
|
```bash
|
||
|
cp config/discourse_defaults.conf config/discourse.conf
|
||
|
```
|
||
|
|
||
|
Et modifiez-le avec votre configuration. Les principales zones d'intérêt sont
|
||
|
la configuration pour la base de données et pour le serveur de messagerie :
|
||
|
|
||
|
```ini
|
||
|
# adresse hôte pour le serveur de base de données
|
||
|
# Ceci est défini à vide pour qu'il essaie d'utiliser les sockets en premier
|
||
|
db_host = localhost
|
||
|
|
||
|
# port du serveur de base de données, pas besoin de le définir
|
||
|
db_port = 5432
|
||
|
|
||
|
# nom de la base de données exécutant discourse
|
||
|
db_name = discourse
|
||
|
|
||
|
# nom d'utilisateur accédant à la base de données
|
||
|
db_username = discourse
|
||
|
|
||
|
# mot de passe utilisé pour accéder à la base de données
|
||
|
db_password = password
|
||
|
```
|
||
|
|
||
|
et pour le serveur SMTP (dans cet exemple, nous utilisons Gmail) :
|
||
|
|
||
|
```ini
|
||
|
# adresse du serveur smtp utilisé pour envoyer des emails
|
||
|
smtp_address = smtp.gmail.com
|
||
|
|
||
|
# port du serveur smtp utilisé pour envoyer des emails
|
||
|
smtp_port = 587
|
||
|
|
||
|
# domaine passé au serveur smtp
|
||
|
smtp_domain = gmail.com
|
||
|
|
||
|
# nom d'utilisateur pour le serveur smtp
|
||
|
smtp_user_name = votre-adresse@gmail.com
|
||
|
|
||
|
# mot de passe pour le serveur smtp
|
||
|
smtp_password = password
|
||
|
|
||
|
# mécanisme d'authentification smtp
|
||
|
smtp_authentication = plain
|
||
|
|
||
|
# activer le chiffrement TLS pour les connexions smtp
|
||
|
smtp_enable_start_tls = true
|
||
|
```
|
||
|
|
||
|
Maintenant, nous pouvons préparer Discourse pour la production :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle exec rake db:migrate
|
||
|
RAILS_ENV=production bundle exec rake assets:precompile
|
||
|
```
|
||
|
|
||
|
Il est temps de démarrer l'application. J'utilise généralement Puma pour
|
||
|
déployer les applications Rails.
|
||
|
|
||
|
Créez le fichier `config/puma.rb` dans le répertoire de Discourse. Le contenu
|
||
|
suivant devrait suffire (pour plus d'informations, voir
|
||
|
[la documentation de Puma]) :
|
||
|
|
||
|
```ruby
|
||
|
#!/usr/bin/env puma
|
||
|
|
||
|
application_path = '/home/discuss.waarp.org/discourse'
|
||
|
directory application_path
|
||
|
environment 'production'
|
||
|
daemonize false
|
||
|
pidfile "#{application_path}/tmp/pids/puma.pid"
|
||
|
state_path "#{application_path}/tmp/pids/puma.state"
|
||
|
bind "unix://#{application_path}/tmp/sockets/puma.socket"
|
||
|
```
|
||
|
|
||
|
À partir de là, l'application peut être exécutée avec la commande suivante :
|
||
|
|
||
|
```bash
|
||
|
bundle exec puma -C config/puma.rb
|
||
|
```
|
||
|
|
||
|
Enfin, configurez Nginx pour transférer les requêtes à Discourse. Créez le
|
||
|
fichier `/etc/nginx/conf.d/discourse.conf` avec le contenu suivant :
|
||
|
|
||
|
```nginx
|
||
|
upstream discourse {
|
||
|
server unix:/chemin/vers/discourse/tmp/sockets/puma.socket;
|
||
|
}
|
||
|
|
||
|
server {
|
||
|
listen 80;
|
||
|
server_name example.com;
|
||
|
|
||
|
location / {
|
||
|
try_files $uri @proxy;
|
||
|
}
|
||
|
|
||
|
location @proxy {
|
||
|
proxy_set_header Host $host;
|
||
|
proxy_set_header X-Real-IP $remote_addr;
|
||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
proxy_pass http://discourse;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Votre forum avec Discourse est configuré !
|
||
|
|
||
|
## Gestion des services
|
||
|
|
||
|
Selon vos habitudes de travail, vous pouvez ajouter des unités systemd pour
|
||
|
exécuter Discourse.
|
||
|
|
||
|
Il nécessite au moins deux service :
|
||
|
|
||
|
1. Sidekiq, qui est utilisé pour traiter les tâches de fond asynchrones
|
||
|
2. Rails, pour Discourse lui-même.
|
||
|
|
||
|
Avec les services configurés, les services peuvent être démarrés/arrêtés/activés
|
||
|
avec les commandes `systemctl`.
|
||
|
|
||
|
Mais avant cela, si vous utilisez RVM, vous devez créer un wrapper pour
|
||
|
l'environnement (ruby local, et gemset optionnel) utilisé par Discourse :
|
||
|
|
||
|
```bash
|
||
|
rvm wrapper 2.3.0 systemd bundle
|
||
|
```
|
||
|
|
||
|
Cela crée un exécutable dans `$rvm_bin_path` que vous pouvez appeler
|
||
|
à la place de bundle, et qui chargera automatiquement le bon environnement.
|
||
|
|
||
|
### Sidekiq
|
||
|
|
||
|
Tout d'abord, créez une configuration pour Sidekiq. Créez le fichier
|
||
|
`config/sidekiq.yml` dans votre projet Discourse avec le contenu
|
||
|
suivant (pour plus d'informations, voir [la documentation de Sidekiq]) :
|
||
|
|
||
|
```yaml
|
||
|
---
|
||
|
:concurrency: 5
|
||
|
:pidfile: tmp/pids/sidekiq.pid
|
||
|
staging:
|
||
|
:concurrency: 10
|
||
|
production:
|
||
|
:concurrency: 20
|
||
|
:queues:
|
||
|
- default
|
||
|
- critical
|
||
|
- low
|
||
|
```
|
||
|
|
||
|
Ensuite, créez l'unité de service pour Sidekiq. Créez le fichier
|
||
|
`/etc/systemd/system/discourse-sidekiq.service` avec le
|
||
|
contenu suivant :
|
||
|
|
||
|
```ini
|
||
|
[Unit]
|
||
|
Description=service sidekiq de discourse
|
||
|
After=multi-user.target
|
||
|
|
||
|
[Service]
|
||
|
WorkingDirectory=/chemin/vers/discourse
|
||
|
Environment=RAILS_ENV=production
|
||
|
ExecStart=/chemin/vers/rvm/.rvm/bin/systemd_bundle exec sidekiq -C config/sidekiq.yml
|
||
|
Restart=always
|
||
|
RestartSec=10
|
||
|
|
||
|
[Install]
|
||
|
WantedBy=multi-user.target
|
||
|
```
|
||
|
|
||
|
### Discourse
|
||
|
|
||
|
Pour Discourse, créez simplement l'unité de service pour Puma. Créez le fichier
|
||
|
`/etc/systemd/system/discourse.service` avec le contenu suivant :
|
||
|
|
||
|
```ini
|
||
|
[Unit]
|
||
|
Description=service discourse
|
||
|
After=discourse-sidekiq.service
|
||
|
Requires=discourse-sidekiq.service
|
||
|
|
||
|
[Service]
|
||
|
WorkingDirectory=/chemin/vers/discourse
|
||
|
Environment=RAILS_ENV=production
|
||
|
ExecStart=/chemin/vers/rvm/.rvm/bin/systemd_bundle exec puma -C config/puma.rb
|
||
|
Restart=always
|
||
|
RestartSec=10
|
||
|
|
||
|
[Install]
|
||
|
WantedBy=multi-user.target
|
||
|
```
|
||
|
|
||
|
## Mises à jour
|
||
|
|
||
|
Les mises à jour sont encore plus faciles :
|
||
|
|
||
|
Lisez d'abord les notes de version.
|
||
|
Faites ensuite des sauvegardes du code et de la base de données.
|
||
|
Maintenant, vous pouvez basculer vers la nouvelle version :
|
||
|
|
||
|
```bash
|
||
|
cd /chemin/vers/discourse
|
||
|
git checkout vX.X.X
|
||
|
```
|
||
|
|
||
|
Installez les nouvelles dépendances, exécutez les migrations et reconstruisez les
|
||
|
assets :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle install
|
||
|
RAILS_ENV=production bundle exec rake db:migrate
|
||
|
RAILS_ENV=production bundle exec rake assets:precompile
|
||
|
```
|
||
|
|
||
|
Redémarrez Discourse :
|
||
|
|
||
|
```bash
|
||
|
systemctl restart discourse
|
||
|
```
|
||
|
|
||
|
Que peut-il mal se passer ? Si je ne donne aucune solution ici, c'est toujours
|
||
|
récupérable (d'où les sauvegardes !).
|
||
|
|
||
|
- La migration de la base de données a échoué (restaurez la base de données avec
|
||
|
votre sauvegarde, corrigez le problème et réessayez !)
|
||
|
- Les plugins ne sont pas compatibles avec la dernière version (revenez à
|
||
|
la solution précédente fonctionnelle et attendez qu'ils soient compatibles)
|
||
|
|
||
|
## Plugins
|
||
|
|
||
|
Les plugins Discourse peuvent être gérés de la même manière.
|
||
|
|
||
|
### Installation de plugins
|
||
|
|
||
|
Installez le plugin avec l'URL de son dépôt :
|
||
|
|
||
|
```bash
|
||
|
cd /chemin/vers/discourse
|
||
|
RAILS_ENV=production bundle exec rake plugin:install[URL]
|
||
|
```
|
||
|
|
||
|
Installez les nouvelles dépendances, exécutez les migrations et reconstruisez les
|
||
|
assets :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle install
|
||
|
RAILS_ENV=production bundle exec rake db:migrate
|
||
|
RAILS_ENV=production bundle exec rake assets:precompile
|
||
|
```
|
||
|
|
||
|
Redémarrez Discourse :
|
||
|
|
||
|
```bash
|
||
|
systemctl restart discourse
|
||
|
```
|
||
|
|
||
|
### Mise à jour
|
||
|
|
||
|
Pour mettre à jour un plugin spécifique, utilisez la commande suivante :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle exec rake plugin:update[ID]
|
||
|
```
|
||
|
|
||
|
Vous pouvez également mettre à jour tous les plugins en une seule fois avec la commande :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle exec rake plugin:update_all
|
||
|
```
|
||
|
|
||
|
Ensuite, installez les nouvelles dépendances, exécutez les migrations et reconstruisez les
|
||
|
assets :
|
||
|
|
||
|
```bash
|
||
|
RAILS_ENV=production bundle install
|
||
|
RAILS_ENV=production bundle exec rake db:migrate
|
||
|
RAILS_ENV=production bundle exec rake assets:precompile
|
||
|
```
|
||
|
|
||
|
et redémarrez Discourse :
|
||
|
|
||
|
```bash
|
||
|
systemctl restart discourse
|
||
|
```
|
||
|
|
||
|
[Discourse]: http://www.discourse.org/
|
||
|
[Documentation de Sidekiq]: https://github.com/mperham/sidekiq/wiki/Advanced-Options
|
||
|
[Documentation de Puma]: https://github.com/puma/puma
|