Etherpad Lite est un éditeur de texte collaboratif Open Source sous licence Apache2.0 né en 2008 et créé par David Greenspan, Aaron Iba et J.D. Zamfirescu. Il permet, via un navigateur, à plusieurs personnes de travailler sur un même document en temps réel, avec un outil de messagerie instantanée intégré. Chaque participant est différencié par une couleur propre modifiable. Etherpad Lite est écrit Javascript et utilise Node.js, il requiert une base de données dont le choix peut se faire parmi plusieurs SGBD : MySQL, MariaDB, MongoDB, Redis ou PostgreSQL. De nombreux plugins sont développés et intégrables pour en décupler les fonctionnalités d’origine, par exemple en apportant la possibilité d’exporter les documents créés au format Microsoft Office ou LibreOffice (abiword est alors nécessaire en paquet complémentaire).
Objectif
L’objectif de cet article est l’installation et la configuration d’un serveur auto-hébergé Ethepad Lite, sur serveur Web Node.js et base de données Redis, en version 1.6.1 sur une distribution Linux Debian Jessie 8.7 32bits.
Schéma logique

Pré-requis
1. Pré-requis avant réalisation
- Un serveur Debian Jessie 8.7 32 bits fonctionnel (installation basique avec utilitaires usuels du système et service SSH)
- Packages de base supplémentaires : sudo, resolvconf, tree
- Domaine utilisé : opensharing.priv
2. Configuration réseau initiale
Serveur Etherpad | |
FQDN | etherpad-test.opensharing.priv |
Adresse IP | 192.168.1.26 |
Réseau | 192.168.1.0/24 |
Passerelle | 192.168.1.1 |
dns-nameservers | 192.168.1.11 192.168.1.12 |
dns-search | opensharing.priv |
Contenu initial du fichier /etc/network/interfaces :
auto lo iface lo inet loopback allow-hotplug eth0 iface eth0 inet static address 192.168.1.26 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 dns-search opensharing.priv dns-nameservers 192.168.1.11 192.168.1.12
Contenu initial du fichier /etc/hosts :
127.0.0.1 localhost.localdomain localhost 192.168.1.26 etherpad-test.opensharing.priv etherpad-test 192.168.1.26 etherpad.opensharing.priv etherpad
Rmq : L’adresse 127.0.1.1 doit être retirée sur un serveur à IP fixe et remplacée par cette dernière, tel que l’exemple ci-dessus.
Contenu initial du fichier /etc/host.conf :
order hosts, bind multi on
Contenu initial du fichier /etc/resolv.conf :
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 192.168.1.11 nameserver 192.168.1.12 search opensharing.priv
Rmq :
Le fichier /etc/resolv.conf ne doit pas être édité dès lors que le paquet resolvconf a été installé.
Pour prendre en compte les modifications des fichiers de configuration relatifs au réseau, redémarrage du service réseau :
# /etc/init.d/networking restart # /etc/init.d/networking reload
Réalisation
1. Installation de paquets complémentaires
# apt install git curl gzip python libssl-dev pkg-config build-essential abiword
Installe les paquets suivants par dépendances :
abiword | abiword-common | abiword-plugin-grammar | abiword-plugin-mathview |
build-essential | curl | fonts-lyx | git |
git-man | gzip | libabiword-3.0 | libcurl3 |
liberror-perl | libgdome2-0 | libgdome2-cpp-smart0c2a | libgoffice-0.10-10 |
libgoffice-0.10-10-common | libgtkmathview0c2a | liblink-grammar4 | libloudmouth1-0 |
libots0 | libssl-dev | libssl-doc | libtidy-0.99-0 |
libwv-1.2-4 | link-grammar-dictionaries-en | pkg-config | python |
rsync | zlib1g-dev |
2. Installation de Node.js
Node.js est utilisé sur Etherpad comme serveur Web. Il est possible d’installer Apache ou Nginx comme reverse proxy redirigeant les requêtes vers le serveur Web Node.js. C’est ce que nous verrons plus loin en utilisant Nginx.
Ce serveur web utilise, par défaut, le port 9001.
# curl -sL https://deb.nodesource.com/setup_7.x | bash -
Installe le dépôt Node.js v7.x en suivante les étapes suivantes :
# apt-get install -y apt-transport-https > /dev/null 2>&1
# curl -sLf -o /dev/null ‘https://deb.nodesource.com/node_7.x/dists/jessie/Release’
# curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add –
# echo ‘deb https://deb.nodesource.com/node_7.x jessie main’ > /etc/apt/sources.list.d/nodesource.list
# echo ‘deb-src https://deb.nodesource.com/node_7.x jessie main’ >> /etc/apt/sources.list.d/nodesource.list
# apt-get update
# apt install -y nodejs
Installe Node.js en version 7.9.0 et npm en version 4.2.0.
3. Installation de Redis
Le serveur Redis est utilisé sur Etherpad comme moteur de base de données, un SGBD key-value NoSQL, permettant par le chargement en RAM des données d’atteindre de hautes performances.
Il est possible d’utiliser MongoDB comme moteur de base de données, un SGBD orienté documents NoSQL, performant également mais probablement moins que Redis, c’est pourquoi nous choisirons la première option. Redis Server utilise par défaut le port 6379 (et MongoDB le port 27017). Etherpad prend en charge les SGBD suivants : MySQL, MariaDB, PostgreSQL, SQLite3, MongoDB et Redis.
# apt install redis-server
Installe les paquets suivants par dépendances :
libjemalloc1 | redis-server | redis-tools |
4. Installation de Nginx
# apt install nginx
Installe les paquets suivants par dépendances :
nginx | nginx-common | nginx-full |
5. Installation de Etherpad Lite
5.1. Téléchargement de Etherpad Lite et création d’un utilisateur système
# mkdir /opt/etherpaddir/ && cd $_ # git clone https://github.com/ether/etherpad-lite.git Clonage dans 'etherpad-lite'... remote: Counting objects: 29031, done. remote: Compressing objects: 100% (107/107), done. Réception d'objets: 100% (29031/29031), 18.85 MiB | 2.12 MiB/s, fait. remote: Total 29031 (delta 55), reused 0 (delta 0), pack-reused 28924 Résolution des deltas: 100% (20660/20660), fait. Vérification de la connectivité... fait. # adduser --system --home=/opt/etherpaddir/etherpad-lite --group etherpadlite # chown -R etherpadlite:etherpadlite /opt/etherpaddir/etherpad-lite/
5.2. Mise en place des logs et de leur rotation
# mkdir /var/log/etherpad-lite # chown etherpadlite:adm /var/log/etherpad-lite
# nano /etc/logrotate.d/etherpadlite
/var/log/etherpad-lite/etherpad-lite.log { daily rotate 7 missingok compress delaycompress missingok }
5.3. Création du service etherpad-lite
# nano /etc/systemd/system/etherpad-lite.service
[Unit] Description=etherpad-lite (real-time collaborative document editing) After=syslog.target network.target [Service] Type=simple User=etherpadlite Group=etherpadlite ExecStart=/opt/etherpaddir/etherpad-lite/bin/run.sh [Install] WantedBy=multi-user.target
# systemctl enable etherpad-lite Created symlink from /etc/systemd/system/multi-user.target.wants/etherpad-lite.service to /etc/systemd/system/etherpad-lite.service. # systemctl start etherpad-lite
5.4. Configuration du démarrage automatique du service etherpad-lite
# nano /etc/init.d/etherpad-lite
#!/bin/sh ### BEGIN INIT INFO # Provides: etherpad-lite # Required-Start: $local_fs $remote_fs $network $syslog # Required-Stop: $local_fs $remote_fs $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: starts etherpad lite # Description: starts etherpad lite using start-stop-daemon ### END INIT INFO PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/node/bin" LOGFILE="/var/log/etherpad-lite/etherpad-lite.log" EPLITE_DIR="/opt/etherpaddir/etherpad-lite" EPLITE_BIN="bin/safeRun.sh" USER="etherpadlite" GROUP="etherpadlite" DESC="Etherpad Lite" NAME="etherpad-lite" set -e . /lib/lsb/init-functions start() { echo "Starting $DESC... " start-stop-daemon --start --chuid "$USER:$GROUP" --background --make-pidfile --pidfile /var/run/$NAME.pid --exec $EPLITE_DIR/$EPLITE_BIN -- $LOGFILE || true echo "done" } #We need this function to ensure the whole process tree will be killed killtree() { local _pid=$1 local _sig=${2-TERM} for _child in $(ps -o pid --no-headers --ppid ${_pid}); do killtree ${_child} ${_sig} done kill -${_sig} ${_pid} } stop() { echo "Stopping $DESC... " if test -f /var/run/$NAME.pid; then while test -d /proc/$(cat /var/run/$NAME.pid); do killtree $(cat /var/run/$NAME.pid) 15 sleep 0.5 done rm /var/run/$NAME.pid fi echo "done" } status() { status_of_proc -p /var/run/$NAME.pid "" "etherpad-lite" && exit 0 || exit $? } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: $NAME {start|stop|restart|status}" >&2 exit 1 ;; esac exit 0
# chmod +x /etc/init.d/etherpad-lite # update-rc.d etherpad-lite defaults # service etherpad-lite start
6. Configuration de Nginx
# nano /etc/nginx/conf.d/etherpad.conf
server { listen 443; server_name etherpad.opensharing.priv; access_log /var/log/nginx/eplite.access.log; error_log /var/log/nginx/eplite.error.log; ssl on; ssl_certificate /etc/ssl/certs/etherpadperso.crt; ssl_certificate_key /etc/ssl/private/etherpadperso.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; location / { proxy_pass http://localhost:9001/; proxy_set_header Host $host; proxy_pass_header Server; # be carefull, this line doesn't override any proxy_buffering on set in a conf.d/file.conf proxy_buffering off; proxy_set_header X-Real-IP $remote_addr; # http://wiki.nginx.org/HttpProxyModule proxy_set_header X-Forwarded-For $remote_addr; # EP logs to show the actual remote IP proxy_set_header X-Forwarded-Proto $scheme; # for EP to set secure cookie flag when https is used proxy_set_header Host $host; # pass the host header proxy_http_version 1.1; # recommended with keepalive connections # WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } } # we're in the http context here map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name etherpad.opensharing.priv; rewrite ^(.*) https://$server_name$1 permanent; }
Génération de la clef privée :
# openssl genrsa -out /etc/ssl/private/etherpadperso.key 1024
Generating RSA private key, 1024 bit long modulus
.....................................++++++
...++++++
e is 65537 (0x10001)
Demande de certificat à partir de la clef :
# openssl req -new -key /etc/ssl/private/etherpadperso.key -out /etc/ssl/certs/etherpadperso.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank. For some fields there will be a default value, if you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:FR State or Province Name (full name) [Some-State]:Ile-de-France Locality Name (eg, city) []:Paris Organization Name (eg, company) [Internet Widgits Pty Ltd]:OpenSharing Organizational Unit Name (eg, section) []:Service Informatique Common Name (e.g. server FQDN or YOUR name) []:etherpad.opensharing.priv Email Address []:admin@opensharing.priv Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:etherpadcertificate An optional company name []:OpenSharing
Construction du certificat :
# openssl x509 -req -days 365 -in /etc/ssl/certs/etherpadperso.csr -signkey /etc/ssl/private/etherpadperso.key -out /etc/ssl/certs/etherpadperso.crt Signature ok subject=/C=FR/ST=Ile-de-France/L=Paris/O=OpenSharing/OU=Service Informatique/CN=etherpad.opensharing.priv/emailAddress=admin@opensharing.priv Getting Private key
# nginx -tc /etc/nginx/nginx.conf
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
7. Configuration de Etherpad Lite
# nano -c /opt/etherpaddir/etherpad-lite/settings.json
Modifier, à partir de la ligne 41 : connexion à la base de donnée Redis d’index 0 :
[...] "dbType" : "redis", "dbSettings" : { "host" : "localhost", "port": "6379", "database" : "0" }, [...]
Modifier, ligne 60 : pur qu’un nouveau document soit complètement vierge
[...] "defaultPadText" : "", [...]
Modifier, ligne 99 : activation de abiword
[...] "abiword" : "/usr/bin/abiword", [...]
Mais aussi décommenter et modifier, à partir de la ligne 127 : connexion de l’administrateur au tableau de bord d’administration
[...] "users": { "etherpadmin": { "password": "etherpadminpw", "is_admin": true }, "etherpaduser": { "password": "etherpadpw", "is_admin": false } }, [...]
Décommenter et modifier, à partir de la ligne 171 : gestion des logs
[...] "loglevel": "DEBUG", "logconfig" : { "appenders": [ { "type": "console" } , { "type": "file" , "filename": "/var/log/etherpad-lite/etherpad-lite.log" , "maxLogSize": 1048576 , "backups": 3 } [...]
Ajout du module de connexion à Redis :
# cd /opt/etherpaddir/etherpad-lite/src/node_modules/ # npm install redis ep_etherpad-lite@1.6.1 /opt/etherpaddir/etherpad-lite/src └─┬ ueberdb2@0.3.0 └── redis@2.7.1
8. Redémarrage des services
# service redis-server restart # service etherpad-lite restart # service nginx restart
9. Première connexion à Etherpad
Saisir, dans la barre d’adresses, l’adresse suivante :
http://etherpad.opensharing.priv
redirigeant automatiquement vers :
https://etherpad.opensharing.priv/
Le répondeur OCSP nous signifie que le certificat n’émane pas d’une autorité de certification reconnue, un message d’avertissement est donc émis.
Cliquer sur Avancé puis Ajouter une exception…
Il suffit ensuite de Confirmer l’exception de sécurité.
L’interface d’Etherpad Lite se lance ensuite, nous proposant de saisir un nom pour notre nouveau pad, ou de laisser Etherpad le choisir pour nous.
Lors de son premier lancement, le chargement est plus ou moins long.
Un pad vierge s’affiche alors, avec les outils basiques d’un éditeur de texte.
Chaque collaborateur se voit attribué une couleur distinctive modifiable. Il est également possible d’activer la messagerie instantanée pour encore plus d’interactivité et de collaboration.
L’accès à l’interface d’administration se fait via l’URL suivant :
https://etherpad.opensharing.priv/admin
Une fois authentifié, il est possible d’augmenter les fonctionnalités d’Etherpad en ajoutant différentes plugins : ajout de couleur au texte, justification du texte, dessin, mise en évidence des collaborateurs, export au format DOC ou PDF, restauration de révisions, l’affichage de la liste des pads sur la page d’index, etc.
Pour aller plus loin
1. Effectuer une sauvegarde manuelle complète
# service etherpad-lite stop # service redis-server stop # mkdir -p /home/adminsys/backup/1.6.1/ # cd /home/adminsys/backup/1.6.1/ # tar -czvf backup-etherpad-20170419.tar.gz -C /opt/ etherpaddir/ # cp -a /var/lib/redis/dump.rdb /home/adminsys/backup/1.6.1/ # service redis-server start # service etherpad-lite start # service nginx restart
2. Effectuer une restauration manuelle complète
# service etherpad-lite stop # service redis-server stop # cd /home/adminsys/backup/1.6.1/ # tar -xzvf backup-etherpad-20170419.tar.gz -C /opt/ # cp -a /home/adminsys/backup/1.6.1/dump.rdb /var/lib/redis/ # service redis-server start # service etherpad-lite start # service nginx restart
3. Effectuer un upgrade de Etherpad Lite
# cd /opt/etherpaddir/etherpad-lite/ # git pull https://github.com/ether/etherpad-lite.git
Références
- Ars Technca – Web Served 8: Node.js, Redis, and real-time writing with Etherpad
- Ars Technica – Web Served Serie
- Ubuntu Documentation – Etherpad Lite Installation
- Framacloud – Installation d’Etherpad
- Wiki Académdie de Versailles – Installer un serveur Etherpad-Lite interne sous Debian
- GitHub – How to deploy Etherpad Lite as a service
- /dev/blob – Installing and configuring etherpad-lite on debian with nginx