Outils pour utilisateurs

Outils du site


public:loomio_reverse_proxy

Loomio derrière un reverse proxy

Pré-requis

  • Pour l'installation de Loomio / Framavox, suivre la documentation rédigée avec soins par Framasoft sur le Framacloud.
  • Pour la création des certificats, le client officiel ayant pas mal bougé ces derniers temps, nous vous conseillons de passer par le site officiel https://letsencrypt.org/. Le tuto Avec un peu d huile de cloud sera également mis à jour prochainement concernant la création des certificats.
  • Deux certificats ont été créés : un pour loomio.example.com et un pour faye.loomio.example.com, et chaque vhost a une configuration séparée dans le reverse proxy (cf. plus bas)

Pourquoi ce tuto

L'utilisation d'un reverse proxy n'est pas en soit une configuration exotique, c'est quelque chose de très pratiqué et qui en général ne pose que très peu voire aucun problème.

Sauf que dans le cas de Loomio, par défaut amené avec l'excellent Let'sEncrypt, cela donne du fil à retordre !
Quel étrange casse-tête… Après des jours à essayer de faire marcher Loomio en reverse proxy, avec des erreurs d'upstream dans les logs nginx du conteneur et ceux du reverse proxy ; un, deux certificats ; un, deux, trois, quatre virtualhosts dans la conf du reverse Nginx, des problèmes de contenu mixed (lorsque le navigateur Web détecte des flux HTTP sur une connexion HTTPS)…

A force de tests, d'échanges (merci à Minus - https://www.debian-fr.org/t/loomio-derriere-un-reverseproxy/70055/6) et un peu aussi d'acharnement, nous sommes finalement arrivé (un peu par hasard !) à faire fonctionner Loomio derrière un reverse proxy Nginx, sans HTTPS côté Loomio, sans warning de contenu mixed sur HTTPS et avec mise à jour dynamique du contenu sans aucun rechargement.

…et toujours des alertes sur l'upstream du NGINX Loomio ! Les erreurs semblent en lien avec le conteneur Worker, mais finalement sans grande gravité.

Au final la configuration détaillée ci-dessous tourne avec un reverse proxy Nginx écoutant en 443 et redirigeant vers le port 80 du Nginx Loomio, c'est merveilleux 😂

Schéma de l'installation

Reverse-proxy Nginx
écoute en HTTPS
Upstream redirige vers
CoreOs HTTP port 8001
CoreOs
écoute sur le port 8001
Redirection gérée par Docker
vers conteneur Nginx en HTTP (port 80)
Docker-compose avec Loomio
loomiodeploy_nginx_1
loomiodeploy_mailin_1
loomiodeploy_loomio_1
loomiodeploy_worker_1
loomiodeploy_db_1
loomiodeploy_faye_1

Configuration Docker-compose

On enlève tout ce qui se rapport à Let'sEncrypt, la partie HTTPS est à la seule charge du reverse proxy. On indique également de ne mapper que le port 8001 vers le port 80 pour Nginx :

docker-compose.yml
#letsencrypt:
#  image: jrcs/letsencrypt-nginx-proxy-companion
#  volumes:
#    - /var/run/docker.sock:/var/run/docker.sock:ro
#    - ./certificates:/etc/nginx/certs:rw
#  volumes_from:
#    - nginx
 
nginx:
  image: jwilder/nginx-proxy
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - ./nginx/vhost.d:/etc/nginx/vhost.d
    - ./nginx/html:/usr/share/nginx/html
  ports:
    - 8001:80
  links:
    - loomio
    - faye
 
loomio:
  image: loomio/loomio
  expose:
   - 3000
  env_file: ./env
  links:
    - db
  environment:
    - DATABASE_URL=postgresql://postgres:password@db/loomio_production
  volumes:
    - ./attachments:/loomio/public/system/
 
worker:
  image: loomio/loomio
  env_file: ./env
  links:
    - db:db
  environment:
    - DATABASE_URL=postgresql://postgres:password@db/loomio_production
  volumes:
    - ./attachments:/loomio/public/system/attachments
  command: "bundle exec rake jobs:work"
 
db:
  image: postgres
  volumes:
    - ./pgdata:/pgdata
  environment:
   - POSTGRES_PASSWORD=password
   - PGDATA=/pgdata
 
mailin:
  image: loomio/mailin-docker
  ports:
    - 25:25
  links:
    - loomio
  environment:
    - WEBHOOK_URL=http://loomio.example.com/email_processor/
 
faye:
  build: faye/.
  env_file: ./faye_env

Pour les fichiers env et faye_env :

env
# this is the hostname of your app used by loomio
CANONICAL_HOST=loomio.example.com
 
# this is to tell nginx that you want requests for this hostname to come to the app
VIRTUAL_HOST=loomio.example.com
 
# this is to configure letsencrypt to automatically issue and renew your hostname
#LETSENCRYPT_HOST=loomio.example.com
#LETSENCRYPT_EMAIL=hostmaster@example.com
 
# the number of dots in your hostname
TLD_LENGTH=2
 
# smtp settings
SUPPORT_EMAIL=postmaster@example.com
SMTP_DOMAIN=loomio.example.com
 
SMTP_SERVER=mail.example.com
SMTP_PORT=25
#SMTP_USERNAME=smtpusername
#SMTP_PASSWORD=smtppassword
 
FAYE_URL=https://faye.loomio.nomagic.fr/faye
REPLY_HOSTNAME=loomio.example.com
 
# helper bot is the account which welcomes people to their groups.
HELPER_BOT_EMAIL=no-reply@loomio.example.com
RAILS_ENV=production
FORCE_SSL=1
DEVISE_SECRET=monDeviseSecret
SECRET_COOKIE_TOKEN=monSecretCookieToken
PRIVATE_PUB_SECRET_TOKEN=monSecretToken
faye_env
# this is to tell nginx that you want requests for this hostname to come to the app
VIRTUAL_HOST=faye.loomio.example.com
 
# this is to configure letsencrypt to automatically issue and renew your hostname
#LETSENCRYPT_HOST=faye.loomio.example.com
#LETSENCRYPT_EMAIL=hostmaster@example.com
 
PRIVATE_PUB_SECRET_TOKEN=monPrivatePubScretToken

Démarrer / redémarrer les conteneurs :

$ docker-compose down
Stopping loomiodeploy_nginx_1 ... done
Stopping loomiodeploy_mailin_1 ... done
Stopping loomiodeploy_loomio_1 ... done
Stopping loomiodeploy_worker_1 ... done
Stopping loomiodeploy_db_1 ... done
Stopping loomiodeploy_faye_1 ... done
Removing loomiodeploy_nginx_1 ... done
Removing loomiodeploy_mailin_1 ... done
Removing loomiodeploy_loomio_1 ... done
Removing loomiodeploy_worker_1 ... done
Removing loomiodeploy_db_1 ... done
Removing loomiodeploy_faye_1 ... done

$ docker-compose up -d
Creating loomiodeploy_faye_1
Creating loomiodeploy_db_1
Creating loomiodeploy_worker_1
Creating loomiodeploy_loomio_1
Creating loomiodeploy_mailin_1
Creating loomiodeploy_nginx_1

Et on contrôle les logs :

docker-compose logs

Reverse proxy Nginx

Côté reverse proxy, on ne déclare que la partie HTTPS. On a créé deux certificats : un pour loomio.example.com et un autre pour faye.loomio.example.com. On a utilisé Let'Encrypt pour générer les certificats.

On déclare 2 hôtes virtuels :

/etc/nginx/sites-enabled/proxy_loomio.conf
## loomio ##############################################
upstream coreos-loomio {
    keepalive 100;
    server coreos.example.com:8001;
 }
 
server {
 
    listen 443 ssl;
    listen [::]:443 ssl;
 
    server_name  
        loomio.example.com
        ;
 
    # SSL specifique
    ssl_certificate           /etc/letsencrypt/certs/loomio_ca.crt;
    ssl_certificate_key       /etc/letsencrypt/private/loomio.key;
    ## HTTPS config
    ssl_session_timeout 10m;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ## Send header to tell the browser to prefer https to http traffic
    add_header Strict-Transport-Security max-age=31536000;
 
    # Logging
    access_log            /var/log/nginx/loomio_access.log;
    access_log            /var/log/nginx/loomio_upstream.log upstreamlog;
    error_log             /var/log/nginx/loomio_error.log;
 
    location / {
      # mêmes paramètres pour tout le monde
      include conf.d/proxy.ini;
 
      # le reste du chemin est en HTTP dans le LAN
      # cf conf.d/upstream.ini
      proxy_pass          http://coreos-loomio;
 
      ## assure de garder le keepalive actif
      proxy_set_header Connection "";
      proxy_read_timeout     300;
      proxy_connect_timeout  300;
    }
}
 
## faye ################################################
upstream coreos-loomio-faye {
    keepalive 100;
    server server coreos.example.com:8001;
}
 
server {
 
    listen 443 ssl;
    listen [::]:443 ssl;
 
    server_name  
        faye.loomio.example.com
        ;
 
    # SSL specifique
    ssl_certificate           /etc/letsencrypt/certs/faye.loomio_ca.crt;
    ssl_certificate_key       /etc/letsencrypt/private/faye.loomio.key;
    ## HTTPS config
    ssl_session_timeout 10m;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ## Send header to tell the browser to prefer https to http traffic
    add_header Strict-Transport-Security max-age=31536000;
 
    # Logging
    access_log            /var/log/nginx/loomio-faye_access.log;
    access_log            /var/log/nginx/loomio-faye_upstream.log upstreamlog;
    error_log             /var/log/nginx/loomio-faye_error.log;
 
    location / {
      # mêmes paramètres pour tout le monde
      include conf.d/proxy.ini;
 
      # le reste du chemin est en HTTP dans le LAN
      proxy_pass          http://coreos-loomio-faye;
 
      ## assure de garder le keepalive actif
      proxy_set_header Connection "";
      proxy_read_timeout     300;
      proxy_connect_timeout  300;
    }
}

Dans notre exemple on utilise un fichier commun pour les paramètres du proxy :

/etc/nginx/conf.d/proxy.ini
# Proxy config
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_redirect          off;
proxy_http_version   1.1;
proxy_next_upstream off;

On test puis redémarre notre reverse-proxy :

# service nginx configtest
Testing nginx configuration:.
# service nginx restart

On se met en écoute sur les logs des hôtes virtuels :

# tail /var/log/nginx/loomio*error.log -f
==> /var/log/nginx/loomio_error.log <==

==> /var/log/nginx/loomio-faye_error.log <==

Cadeau bonux

Pendant les longues heures passées à chercher ce qui n'allait pas, nous avons glané quelques infos pratiques sur Loomio, on les rassemble ici :

Accéder à l'interface d'administration du site

Sur l'hôte hébergeant Loomio :

  • Rentrer dans le conteneur db
docker exec -i -t loomiodeploy_db_1 /bin/bash
  • Se connecter à la base de données
psql -dloomio_production -Upostgres -W

⇒ mot de passe par défaut = password

  • Afficher la liste des utilisateurs
select id, email, is_admin from users;
  • Rendre un utilisateur administrateur
update users set is_admin=true where email='myemail@example.com';

⇒ veiller à ce cet utilisateur soit le seul à posséder cet email (je pense que loomio bloque la création de 2 utilisateurs ayant le même courriel, mais je n'ai pas vérifié).

Vous pouvez maintenant accéder à l'interface d'administration sur https://loomio.example.com/admin, en faisant attention à ne rien casser (!)

Changer le mot de passe PostGreSQL

Si ça vous gêne d'avoir un mot de passe password, indépendamment du fait que la base n'est pas accessible directement depuis l'extérieur, voilà comment procéder :

Sur l'hôte hébergeant Loomio :

  • Rentrer dans le conteneur db
docker exec -i -t loomiodeploy_db_1 /bin/bash
  • Se connecter à la base de données
psql -dpostgres -Upostgres -W
postgres=# \password postgres
(affiché dans la console postgresql) Enter new password:  
(affiché dans la console postgresql) Enter it again: 
  • Déconnectez-vous (Ctrl-d), tester de vous reconnecter avec le nouveau mot de passe.
  • Sortir du conteneur pour revenir sur l'hôte (exit)
  • Modifier le fichier docker-compose.yml en reportant le changement de mot de passe
  • Démarrer / redémarrer les conteneurs :
$ docker-compose down
Stopping loomiodeploy_nginx_1 ... done
Stopping loomiodeploy_mailin_1 ... done
Stopping loomiodeploy_loomio_1 ... done
Stopping loomiodeploy_worker_1 ... done
Stopping loomiodeploy_db_1 ... done
Stopping loomiodeploy_faye_1 ... done
Removing loomiodeploy_nginx_1 ... done
Removing loomiodeploy_mailin_1 ... done
Removing loomiodeploy_loomio_1 ... done
Removing loomiodeploy_worker_1 ... done
Removing loomiodeploy_db_1 ... done
Removing loomiodeploy_faye_1 ... done

$ docker-compose up -d
Creating loomiodeploy_faye_1
Creating loomiodeploy_db_1
Creating loomiodeploy_worker_1
Creating loomiodeploy_loomio_1
Creating loomiodeploy_mailin_1
Creating loomiodeploy_nginx_1
  • Et on contrôle les logs :
docker-compose logs

Liens

Pour tester l'application ou procéder à son installation, c'est par là !

public/loomio_reverse_proxy.txt · Dernière modification: 2016/07/09 16:13 par jean-yves.michaud