====== 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 [[http://framacloud.org/cultiver-son-jardin/installation-de-loomio/| 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 [[public:avec_un_peu_d_huile_de_cloud|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 :joy: ===== Schéma de l'installation ===== | |!@4| | | AAA |AAA=**Reverse-proxy Nginx** \\ écoute en HTTPS \\ Upstream redirige vers \\ CoreOs HTTP port 8001 | |!@4| | | BBB |BBB=**CoreOs** \\ écoute sur le port 8001 \\ Redirection gérée par Docker \\ vers conteneur Nginx en HTTP (port 80) | |:| | | |L|~@2| CCC |CCC=**Docker-compose avec Loomio** | | | |!| | | | | |)|~| DDD |DDD=loomiodeploy_nginx_1 | | | |!| | | | | |)|~| DDD |DDD=loomiodeploy_mailin_1 | | | |!| | | | | |)|~| DDD |DDD=loomiodeploy_loomio_1 | | | |!| | | | | |)|~| DDD |DDD=loomiodeploy_worker_1 | | | |!| | | | | |)|~| DDD |DDD=loomiodeploy_db_1 | | | |!| | | | | |`|~| DDD |DDD=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 : #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** : # 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 # 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 : ## 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 : # 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à ! * https://framavox.org/ * http://framacloud.org/cultiver-son-jardin/installation-de-loomio/