diff --git a/acme-copy-certs/.gitignore b/acme-copy-certs/.gitignore
deleted file mode 100644
index 38ce4278b6f53ca9c84b17a805fab69689273e86..0000000000000000000000000000000000000000
--- a/acme-copy-certs/.gitignore
+++ /dev/null
@@ -1,123 +0,0 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-pip-wheel-metadata/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-.hypothesis/
-.pytest_cache/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-.python-version
-
-# pipenv
-#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-#   However, in case of collaboration, if having platform-specific dependencies or dependencies
-#   having no cross-platform support, pipenv may install dependencies that don’t work, or not
-#   install all needed dependencies.
-#Pipfile.lock
-
-# celery beat schedule file
-celerybeat-schedule
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
diff --git a/acme-copy-certs/Dockerfile b/acme-copy-certs/Dockerfile
deleted file mode 100644
index 337bea601f7c452381cd37e7716684c74f521567..0000000000000000000000000000000000000000
--- a/acme-copy-certs/Dockerfile
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM alpine:3.9
-
-WORKDIR /usr/src/app
-COPY requirements.txt ./
-
-RUN apk add --no-cache python3 && \
-    python3 -m ensurepip && \
-    rm -r /usr/lib/python*/ensurepip && \
-    pip3 install --upgrade pip setuptools -r requirements.txt && \
-    rm -r /root/.cache
diff --git a/acme-copy-certs/README.md b/acme-copy-certs/README.md
deleted file mode 100644
index fa57959406502189a96761b5395d9aa1c50b3d32..0000000000000000000000000000000000000000
--- a/acme-copy-certs/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# ACME Copy certs 
-
-Ce service permet l'exploitation des certificats TLS générés par Traefik 
-par d'autres serveurs pour leur propres besoins de chiffrement de connexions.
-
-Traefik a la capacité d'automatiser la demande et le renouvellement de certificats
-TLS auprès de services en ligne tels que [Let's Encrypt](https://letsencrypt.org)
-pour assurer le chiffrement des connexions HTTPS aux sites web dont il a la charge.
-
-L'idée est de déléguer la gestion de certificats utilisés par d'autres services dans
-d'autres conteneurs à Traefik, ce qui présente les avantages suivants :
-  * Les certificats générés sont signés par une autorité de certification publique dont les 
-    certificats sont déjà présents sur la plupart des systèmes, ce qui facilite la 
-    vérification de l'authenticité des certificats par rapport à des certificats auto-signés (pas 
-    de certificats de signature à déployer)
-  * A leur expiration, les certificats sont automatiquement renouvelés, ce qui élimine au tâche d'administration
-    et garantit la disponibilité continue des services
\ No newline at end of file
diff --git a/acme-copy-certs/app/cert_updater.py b/acme-copy-certs/app/cert_updater.py
deleted file mode 100644
index da5a24ae43c134d08d4945726a7e72d0e2c430ef..0000000000000000000000000000000000000000
--- a/acme-copy-certs/app/cert_updater.py
+++ /dev/null
@@ -1,200 +0,0 @@
-""" Traefik Certificate extraction and update module
-
-Provides tools to extract TLS certificates from Treafik acme.json files.
-
-Classes
--------
-    
-    CertUpdater:
-        This class handles acme files decoding and stores or updates the resulting
-        certificates in separate folders.
-"""
-
-import os
-import errno
-import json
-from base64 import b64decode
-
-class CertUpdater:
-    """Decodes acme files and extact the resulting certificates if needed.
-
-    This class keeps flat certificates for specified domain names 
-    in sync with the contents of an acme.json file. The certificates are stored in separated
-    subdirectories named after the main domain name they are valid for.
-    If the certificates specify x509 SAN records, only the main CN is used (a single 
-    directory is created, regardless of the number of alternate names.)
-
-    Attributes
-    ----------
-        acme_file : str
-            Name of the acme.json file containing the certificates
-        names : list 
-            List of domain names to keep updated
-        certs_root_path : str
-            Directory where the certificates will be stored. The certificates are
-            stored in subdirectories of this directory
-
-    Methods
-    -------
-        add(name)
-            Adds a domain name to the updater
-
-        remove(name)
-            Removes a domain name from the updater
-
-        update()
-            Decodes the acme.json file and updates the certicates that need to be updated.
-
-
-
-    """
-    def __init__(self, acme_file, certs_root_path):
-        """
-        Parameters
-        ----------
-            acme_file : str
-                path of the acme file containing the certificates
-            certs_root_path : str 
-                root directory where certificates will be extracted. 
-                They are extracted in subdirectories named after the CN stored in
-                the certificate.
-        """
-        self.acme_file = acme_file
-        self.names = []
-        self.certs_root_path = certs_root_path + '/'
-
-    def add(self, name):
-        """Adds a domain name to the updater.
-
-        Parameters
-        ----------
-            name : str
-                domain name to add
-        """
-        
-        self.names.append(name)
-
-        # Create directories etc if they do not exist
-        try:
-            os.makedirs(self.certs_root_path + name + '/')
-        except OSError as error:
-            if error.errno != errno.EEXIST:
-                raise
-        
-    def remove(self, name):
-        """Removes a domain name from the updater.
-
-        Parameters
-        ----------
-            name : str
-                domain name to remove
-        """
-
-        try:
-            self.names.remove(name)
-        except ValueError:
-            pass
-
-    def update(self):
-        """Decodes the acme.json file and updates the certicates that need to be updated.
-
-        Returns
-        -------
-            list
-                a list of domain names that have been updated. An empty list if no certificate
-                has been updated.
-        """
-
-        # Open and decode the acme file
-        try:
-            with open(self.acme_file) as acme:
-                data = json.loads(acme.read())
-        except FileNotFoundError:
-            print('ACME file {0} not found when trying to decode.'.format(self.acme_file))
-            return []
-        except json.JSONDecodeError:
-            print('File {0} does not look like an ACME file.'.format(self.acme_file))
-            return []
-
-        # Get the acme file version
-        try:
-            acme_ver = 2 if 'acme-v02' in data['Account']['Registration']['uri'] else 1
-        except TypeError:
-            if 'DomainsCertificate' in data:
-                acme_ver = 1
-            else:
-                acme_ver = 2
-
-        # Get the certificates
-        if acme_ver == 1:
-            certs = data['DomainsCertificate']['Certs']
-        elif acme_ver == 2:
-            certs = data['Certificates']
-
-        # Iterate over certificates. If a certificate has been updated,
-        # add its name to the updated_names.
-        updated_names = []
-        
-        for c in certs:
-            if acme_ver == 1:
-                name = c['Certificate']['Domain']
-                key = c['Certificate']['PrivateKey']
-                fullchain = c['Certificate']['Certificate']
-            elif acme_ver == 2:
-                name = c['Domain']['Main']
-                key = c['Key']
-                fullchain = c['Certificate']
-
-            if name in self.names:
-                key = b64decode(key).decode('utf-8')
-                fullchain = b64decode(fullchain).decode('utf-8')
-                chain_start = fullchain.find('-----BEGIN CERTIFICATE-----', 1)
-                cert = fullchain[0:chain_start]
-                chain = fullchain[chain_start:] 
-            
-                print('Updating certificates for {0}'.format(name))
-                if self._needs_updating(name, fullchain):
-                    path = self.certs_root_path + name + '/'
-                    with open(path + 'privkey.pem', 'w') as f:
-                        f.write(key)
-
-                    with open(path + 'cert.pem', 'w') as f:
-                        f.write(cert)
-
-                    with open(path + 'chain.pem', 'w') as f:
-                        f.write(chain)
-
-                    with open(path + 'fullchain.pem', 'w') as f:
-                        f.write(fullchain)
-                    
-                    print('Certificates updated')
-
-                    updated_names.append(name)
-                else:
-                    print('Cetificates are already up-to-date')
-    
-        return updated_names
-
-    def _needs_updating(self, name, fullchain):
-        """Checks if a certificate has changed
-
-        Parameters
-        ----------
-            name : str
-                Name of the directory containing the certificates
-            fullchain : str
-                Full certificates extracted from the acme.json file
-
-        Returns
-        -------
-            bool
-                True if the contents of the current certificates are
-                different from the fullchain. False otherwise.
-        """
-
-        path = self.certs_root_path + name + '/fullchain.pem'
-        try:
-            with open(path, 'r') as f:
-                return f.read() != fullchain
-        except FileNotFoundError:
-            return True        
\ No newline at end of file
diff --git a/acme-copy-certs/app/docker_actions.py b/acme-copy-certs/app/docker_actions.py
deleted file mode 100644
index 06735e64313217ba528c50ac63f2954004ff9a08..0000000000000000000000000000000000000000
--- a/acme-copy-certs/app/docker_actions.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import docker
-
-class DockerAction:
-    def __init__(self, docker_client, container_id):
-        self.client = docker_client
-        self.container_id = container_id
-        pass
-
-    def exec(self, id):
-        c = self.client.container.get(self.container_id)
-
-        if c.status == 'running':
-            self.action(c)
-
-    def action(self, container):
-        pass
-
-class RestartDockerAction(DockerAction):
-    def __init__(self, docker_client, container_id):
-        super().__init__(docker_client, container_id)
-
-    def action(self, container):
-        try:
-            container.restart()
-        except docker.errors.APIError:
-            print('Unable to restart container {0}({1})'.format(container.name,
-                container.id))
-
-class KillDockerAction(DockerAction):
-    def __init__(self, docker_client, container_id, signal='SIGKILL'):
-        super().__init__(docker_client, container_id)
-        self.signal = signal
-
-    def action(self, container):
-        try:
-            container.kill(self.signal)
-        except docker.errors.APIError:
-            print('Unable to kill container {0}({1}) with signal {2}'
-                .format(container.name, self.container_id, self.signal))
\ No newline at end of file
diff --git a/acme-copy-certs/app/docker_monitor.py b/acme-copy-certs/app/docker_monitor.py
deleted file mode 100644
index 13e41ca600173877ee9c12570b7d4a329584dd62..0000000000000000000000000000000000000000
--- a/acme-copy-certs/app/docker_monitor.py
+++ /dev/null
@@ -1,120 +0,0 @@
-"""Docker event monitoring
-
-Provides a monitor for docker events that add/remove services when
-they occur according to the configuration provided in the labels of these
-services.
-
-Classes
--------
-    DockerMonitor
-        A monitor for docker events.
-"""
-
-import docker
-import threading
-import requests
-
-from service_manager import Service
-from docker_actions import RestartDockerAction
-from docker_actions import KillDockerAction
-
-class DockerMonitor(threading.Thread):
-    """Implements a docker events monitoring thread.
-
-    This class implements a thread that listen to the docker socket to intercept
-    events on specific containers to launch actions on these when start and stop events occur.
-    Containers that should be monitored are identified by labels.
-
-    """
-    def __init__(self, services_mgr):
-        self.docker_client = docker.from_env()
-        self.events = None
-        self.services_mgr = services_mgr
-        super().__init__()
-
-    def run(self):
-        print('Starting monitor')
-        # Identify all running containers and get dependent services 
-        # at startup
-        try:
-            containers = self.docker_client.containers.list()
-
-            for c in containers:
-                if c.status == 'running':
-                    self._add_service(c)
-        
-            # Then, wait for docker events and identify new dependent services
-            # or services that exit the system. Do an update each time a new 
-            # service is added / restarted etc. or a service is changed.
-            self.events = self.docker_client.events(decode = True)
-            for event in self.events:
-                if 'status' not in event:
-                    continue
-
-                try:
-                    c = self.docker_client.containers.get(event['id'])
-                    if event['status'] == 'stop':
-                        self._remove_service(c)
-                    elif event['status'] == 'start':
-                        self._add_service(c)
-
-                except docker.errors.NotFound:
-                    pass
-                except docker.errors.APIError as error:
-                    print('Docker error while looking up container {0}: {1} '.format(event.id, error.strerror))
-        except requests.exceptions.ConnectionError as error:
-            print('Connection to docker socket refused.')
-        
-        print('No more events to handle: stopping monitor')
-            
-    def stop(self):
-        if self.events is not None:
-            self.events.close()
-            self.join()
-    
-    def _get_host_from_traefik_rule(self, container):
-        if 'traefik.frontend.rule' in container.labels:
-            try:
-                return container.labels['traefik.frontend.rule'].split('Host:')[1].split(',')[0].strip()
-            except IndexError:
-                return ''
-
-    def _get_action_from_label(self, container):
-        if 'acme_copy_certs.action' not in container.labels:
-            return None
-
-        try:
-            action = container.label('acme_copy_certs.action')
-            if action[0].strip() == 'kill':
-                if len(action) == 1:
-                    return KillDockerAction(self.docker_client, container.id, 'SIGHUP')
-                else:
-                    return KillDockerAction(self.docker_client, container.id, action[1].strip())
-             elif action[0].strip() == 'restart':
-                return RestartDockerAction(self.docker_client, container.id)
-            else:
-                return None
-
-        except IndexError:
-            print('Invalid action')
-            return None
-
-    def _add_service(self, container):
-        if 'acme_copy_certs.enable' in container.labels:
-            if container.labels['acme_copy_certs.enable'] == 'true':
-                host = self._get_host_from_traefik_rule(container)
-            elif container.labels['acme_copy_certs.enable'] == 'false':
-                pass
-            else:
-                print('Invalid acme_copy_certs.enable value for {0}'
-                      .format(container.name))
-            
-            if host:
-                print('Handling container {0}({1})'.format(container.name, container.id))
-                s = Service(container.id, host, self._get_action_from_label(container))
-                self.services_mgr.add(s)
-        else:
-            print('Not handling container {0}({1})'.format(container.name, container.id))
-
-    def _remove_service(self, container):
-        self.services_mgr.remove(container.id)
\ No newline at end of file
diff --git a/acme-copy-certs/app/file_watcher.py b/acme-copy-certs/app/file_watcher.py
deleted file mode 100644
index 580041be3b6193eada13aaf8013e6745c4cfc47f..0000000000000000000000000000000000000000
--- a/acme-copy-certs/app/file_watcher.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import os
-from watchdog.observers import Observer
-from watchdog.events import PatternMatchingEventHandler
-
-class FileWatcher:
-    def __init__(self, file_path, handler):
-        self.observer = Observer()
-        abs_path, file_name = os.path.split(os.path.abspath(file_path))
-        self.observed_path = abs_path
-        self.observed_file = file_name
-        self.handler = handler
-
-        self.event_handler = PatternMatchingEventHandler(
-            patterns=['*/' + file_name],
-            ignore_patterns=[],
-            ignore_directories=True)
-
-        self.event_handler.on_any_event = self._on_any_event
-
-        self.observer.schedule(self.event_handler,
-            self.observed_path,
-            recursive=False)
-        
-    def _on_any_event(self, event):
-        self.handler()
-
-    def start(self):
-        print('Starting observing file {0} in directory {1}'.format(self.observed_file, self.observed_path))
-        self.observer.start()
-
-    def stop(self):
-        self.observer.stop()
-        self.observer.join()
\ No newline at end of file
diff --git a/acme-copy-certs/app/service_manager.py b/acme-copy-certs/app/service_manager.py
deleted file mode 100644
index b20e84dcdba18b7d44df4cbe20143c8f4ad60448..0000000000000000000000000000000000000000
--- a/acme-copy-certs/app/service_manager.py
+++ /dev/null
@@ -1,139 +0,0 @@
-"""Handling of docker services
-
-This module provides a ServicesManager class implementing a collection of
-services whose certificates are to be updated by the ssytem.
-
-Classes
--------
-    Service
-        A class representing a single service
-    
-    ServiceManager
-        A class handling a collection of services
-"""
-
-from threading import Lock
-
-class Service:
-    """
-    A service wrapper This object represents a docker service
-
-    Attributes
-    ----------
-
-    id : int
-        The id of the container running the service
-    host : str
-        The hostname associated with the service used for CN in TLS certs
-    action : DockerAction
-        An action to perform on the service when the run_action method is
-        invoked.
-
-    Methods
-    -------
-
-    run_action()
-        Runs the action bound to this service
-    """
-
-    def __init__(self, id, host, action):
-        """
-        Parameters
-        ----------
-        id : int
-            The id of the container running the service
-        host : str
-            The hostname associated with the service used for CN in TLS certs
-        action : DockerAction
-            An action to perform on the service when the run_action method is invoked. 
-        """   
-
-        self.id = id
-        self.host = host
-        self.action = action
-
-    def run_action(self):
-        """Executes the action on the container associated to the service."""
-        if self.action is not None:
-            self.action.exec(self.id)
-
-class ServicesManager:
-    """
-    A ServicesManager handles a collection of services and forwards certicate update
-    requests to a CertUpdater. If a service certificate is updated (either after adding a
-    service or after an explicit update request), the docker action associated
-    with the service is executed.
-
-    Attribures
-    ----------
-        services_by_id : dict
-            A dictionnary of the managed services identified by their container id.
-        services_by_host : dict
-            A dictionnary of the managed services identified by the CN of their
-            certificates.
-        updater : CertUpdater object
-            The certificates updater in charge of handling the certificates for the managed
-            services 
-    
-    Methods
-    -------
-        add(service)
-            Adds a new service to the collection
-
-        remove(id)
-            Removes a service from the collection based on its container id
-
-        update()
-            Checks if any certificate for a managed service needs to be updated. If
-            so, performs the docker action associated with the service on its 
-            container
-    """
-
-    def __init__(self, updater):
-        """
-        Parameters
-        ----------
-            updater : CertUpdater
-                The CertUpdater used to handle certificates for the services
-        """
-        self.services_by_id = {}
-        self.services_by_host = {}
-        self.updater = updater
-        self.lock = Lock()
-
-    def add(self, service):
-        """ Adds a service to the collection and enables handling of its 
-        certificates
-        """
-        with self.lock:
-            self.services_by_id[service.id] = service
-            if service.host not in self.services_by_host:
-                self.services_by_host[service.host] = [service]
-            else:
-                self.services_by_host[service.host].append(service)
-        
-            self.updater.add(service.host)
-        self.update()
-
-    def remove(self, id):
-        """ Removes a service by its id from the collection and disables handling
-        of its certificates
-        """
-        with self.lock:
-            if id in self.services_by_id:
-                service = self.services_by_id[id] 
-                host = service.host
-                self.services_by_host[host].remove(service)
-                del self.services_by_id[id]
-                if len(self.services_by_host[host]) == 0:
-                    del self.services_by_host[host]
-                    self.updater.remove(host)
-
-    def update(self):
-        """ Updates the certificates of the services if needed. If a certificate
-        has changed, exectute the associated docker action on the service container.
-        """
-        with self.lock:
-            for h in self.updater.update():
-                for s in self.services_by_host[h]:
-                    s.run_action()
\ No newline at end of file
diff --git a/acme-copy-certs/requirements.txt b/acme-copy-certs/requirements.txt
deleted file mode 100644
index c546145a62c9e8123dbbe26981510ce150404eea..0000000000000000000000000000000000000000
--- a/acme-copy-certs/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-docker
-watchdog
diff --git a/acme-copy-certs/tests/test.py b/acme-copy-certs/tests/test.py
deleted file mode 100755
index 9772682d64e5dcc9a973f26b76e156d22378581b..0000000000000000000000000000000000000000
--- a/acme-copy-certs/tests/test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-
-import sys, os
-sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../app')
-
-import time
-import cert_updater
-import file_watcher
-import docker_monitor
-import service_manager
-
-
-if __name__ == "__main__":
-    u = cert_updater.CertUpdater('./acme.json', '.')
-
-
-    sm = service_manager.ServicesManager(u)
-
-    f = file_watcher.FileWatcher('./acme.json', sm.update)
-    dm = docker_monitor.DockerMonitor(sm)
-    
-    f.start()
-    dm.start()
-    
-    try:
-        while True:
-           time.sleep(1) 
-    except KeyboardInterrupt:
-        dm.stop()
-        f.stop()
diff --git a/doc/guide_bonnes_pratiques.md b/doc/guide_bonnes_pratiques.md
index 84c748c835b2afeec9ea5d0f55c2f4595bf566ce..526337f5464d3c9d18d430e16a4711784a489320 100644
--- a/doc/guide_bonnes_pratiques.md
+++ b/doc/guide_bonnes_pratiques.md
@@ -112,30 +112,37 @@ Il est suggéré d'éviter les volumes déclarés `external` :
 
 ## Reverse-proxy
 
-Si le service est un service **HTTP(S)** (*i.e.* Web), on utilisera systématiquement le reverse-proxy [Traefik](https://wiki.picasoft.net/doku.php?id=technique:infrastructure:archi#traefik) et on bindera **pas** son port interne sur un port de l'hôte.
+Si le service est un service **HTTP(S)** (*i.e.* Web), on utilisera systématiquement le reverse-proxy Traefik et on bindera **pas** son port interne sur un port de l'hôte.
 
 En effet, Traefik permet de gérer tout pour nous : la redirection vers le bon conteneur et le bon port en fonction du nom de domaine, la création et le renouvellement des certificats, etc.
 
-Il suffit pour ce faire d'ajouter les bons labels, et d'ajouter le conteneur au réseau par défaut de Traefik, qui s'appelle `docker_default`, et existe indépendamment de Docker Compose.
+Il suffit pour ce faire d'ajouter les bons labels, et d'ajouter le conteneur au réseau par défaut de Traefik, qui s'appelle `proxy`, et existe indépendamment de Docker Compose.
 
 Exemple à reprendre :
 
 ```yaml
 networks:
-  docker_default:
+  proxy:
     external: true
 
 services:
   exemple:
     networks:
-      - docker_default
+      - proxy
     labels:
       # Traefik va prendre ce conteneur en compte
       traefik.enable: true
+      # websecure correspond au port 443 de la machine (config Traefik)
+      # Remplacer <exemple> par le nom du conteneur
+      traefik.http.routers.<exemple>.entrypoints: websecure
       # Il redirigera vers ce port, exposé par le conteneur
-      traefik.port: <port>
+      # Remplacer <exemple> par le nom du conteneur
+      # Remplacer app.picasoft.net par l'URL souhaitée
+      traefik.http.routers.<exemple>.rule: Host(`app.picasoft.net`)
       # Lorsque l'utilisateur consulte cette URL
-      traefik.frontend.rule: <exemple>.picasoft.net
+      # Remplacer <exemple> par le nom du conteneur
+      # Remplacer 80 par le port du service
+      traefik.http.services.<exemple>.loadbalancer.server.port: 80
 ```
 
 ## Healthcheck
@@ -182,7 +189,7 @@ Ce qui nous donnerait quelque chose comme :
 networks:
   # C'est le réseau dans lequel se trouve
   # Traefik sur toutes les machines.
-  docker_default:
+  proxy:
     external: true
   # Ce réseau est créé uniquement pour
   # ce fichier Compose.
@@ -190,11 +197,11 @@ networks:
 
 services:
   exemple:
-    # On voit que le service est dans le réseau docker_default, pour être
+    # On voit que le service est dans le réseau proxy, pour être
     # accessible depuis Traefik, mais aussi dans le réseau db, pour
     # pouvoir parler à la base de données.
     networks:
-      - docker_default
+      - proxy
       - db
   # La base de donnée n'est que dans son réseau, et n'est donc
   # pas accessible depuis Internet.
diff --git a/doc/update_and_test.md b/doc/update_and_test.md
index 09caf7459677fe21efae571fa6a2de277503d1ca..66cc18e30d3f51f86f0e3ada30f8960202060c5a 100644
--- a/doc/update_and_test.md
+++ b/doc/update_and_test.md
@@ -114,7 +114,7 @@ Si nécessaire. Certains services ne sont pas accessibles depuis Internet.
 
 Remplacez les URL de production (`.picasoft.net`) par des URL de tests (`.test.picasoft.net`), sauf dans le nom de l'image :
 
-* Si le service utilise Traefik, voir du côté de `traefik.frontend.rule` dans le fichier Compose
+* Si le service utilise Traefik, voir du côté de `traefik.http.services.<service>.loadbalancer.server.port` dans le fichier Compose
 * Si le service utilise des fichiers de configuration, remplacez les références aux URL...
 
 ### Créer les fichiers d'example
diff --git a/pica-db-backup/docker-compose.yml b/pica-db-backup/docker-compose.yml
index 12f10294a310078b6bc7d7d61ec32273dd81afef..fa14ae6a2b5e34e991f214e42017014905a5a800 100644
--- a/pica-db-backup/docker-compose.yml
+++ b/pica-db-backup/docker-compose.yml
@@ -6,12 +6,9 @@ networks:
   etherpad_week:
     name: "etherpad_week"
   plume:
-    name: plume
+    name: "plume"
   wekan:
     name: "wekan"
-  docker_default:
-    external: true
-    name: "docker_default"
 
 services:
   db-backup:
@@ -24,7 +21,6 @@ services:
     env_file:
       - ./secrets/db.secrets
     networks:
-      - docker_default
       - etherpad_main
       - etherpad_week
       - plume
diff --git a/pica-dokuwiki/Dockerfile b/pica-dokuwiki/Dockerfile
index 150d3118c50e47f145dd9226d70750fa770ab467..4a8eaadd9fe7864800ff688aa8e06852f56b561c 100644
--- a/pica-dokuwiki/Dockerfile
+++ b/pica-dokuwiki/Dockerfile
@@ -34,7 +34,6 @@ RUN apt-get update -y && \
     chown -R www-data . && \
     chmod +x /run.sh && \
     sed -i "s/\${MAXSIZE}/100M/g" /etc/nginx/nginx.conf && \
-    apt-get remove -y wget && \
     apt-get autoremove -y && \
     apt-get clean
 
@@ -45,6 +44,6 @@ ENV LANGUAGE fr_FR.UTF-8
 EXPOSE 80
 VOLUME ["/var/www/html"]
 
-HEALTHCHECK CMD wget -q -O /dev/null http://127.0.0.1:${DOKUWIKI_PORT:=80}/
+HEALTHCHECK CMD curl http://127.0.0.1:${DOKUWIKI_PORT:=80}/
 
 CMD ["/run.sh"]
diff --git a/pica-dokuwiki/docker-compose.yml b/pica-dokuwiki/docker-compose.yml
index 79cdf89c37d19c065922cc3e41c26de6df11f577..985279da1bb54b72116a21b91dc8fe8e905c4cd2 100644
--- a/pica-dokuwiki/docker-compose.yml
+++ b/pica-dokuwiki/docker-compose.yml
@@ -1,11 +1,11 @@
-version : "2.4"
+version : "3.7"
 
 volumes:
   dokuwiki-app:
     name: "dokuwiki-app"
 
 networks:
-  docker_default:
+  proxy:
     external: true
 
 services:
@@ -15,15 +15,11 @@ services:
     container_name: dokuwiki-app
     volumes:
       - dokuwiki-app:/var/www/html
-    security_opt:
-      - no-new-privileges
-    mem_limit: "2048m"
-    cpus: "0.20"
-    pids_limit: 1024
     labels:
-      - "traefik.frontend.rule=Host:wiki.picasoft.net"
-      - "traefik.port=80"
-      - "traefik.enable=true"
+      traefik.http.routers.dokuwiki-app.entrypoints: websecure
+      traefik.http.routers.dokuwiki-app.rule: Host(`wiki.picasoft.net`)
+      traefik.http.services.dokuwiki-app.loadbalancer.server.port: 80
+      traefik.enable: true
     restart: unless-stopped
     networks:
-      - docker_default
+      - proxy
diff --git a/pica-etherpad/docker-compose.yml b/pica-etherpad/docker-compose.yml
index 44bf014b5adb40a5f83680e2f4b2f2daa65cb2b1..f4983807f0cfe97bab3f8e71d1f8a16f292e5c66 100755
--- a/pica-etherpad/docker-compose.yml
+++ b/pica-etherpad/docker-compose.yml
@@ -1,4 +1,4 @@
-version : "2.4"
+version : "3.7"
 
 volumes:
   etherpad-db:
@@ -12,33 +12,26 @@ volumes:
 
 networks:
   standard:
-    name: "etherpad_main"
+    name: etherpad_main
   week:
-    name: "etherpad_week"
-  docker_default:
+    name: etherpad_week
+  proxy:
     external: true
-    name: "docker_default"
 
 services:
   etherpad-app:
     image: registry.picasoft.net/pica-etherpad:1.8.4
     build: .
     container_name: etherpad-app
-    depends_on:
-      - etherpad-db
-    security_opt:
-      - no-new-privileges
-    mem_limit: "2048m"
-    cpus: 0.6
-    pids_limit: 1024
     env_file: ./secrets/etherpad-app.secrets
     volumes:
       - ./settings.json:/opt/etherpad-lite/settings.json
       - deleted-pads-standard:/opt/etherpad-lite/deleted_pads
     labels:
+      traefik.http.routers.etherpad-app.entrypoints: websecure
+      traefik.http.routers.etherpad-app.rule: Host(`pad.picasoft.net`)
+      traefik.http.services.etherpad-app.loadbalancer.server.port: 8080
       traefik.enable: true
-      traefik.frontend.rule: "Host:pad.picasoft.net"
-      traefik.port: 8080
     environment:
       DB_HOST: "etherpad-db"
       LOGLEVEL: "INFO"
@@ -47,45 +40,36 @@ services:
       THEME: "colibris"
       TITLE: "Picapad"
       TRUST_PROXY: "true"
-    restart: unless-stopped
     networks:
-      - docker_default
+      - proxy
       - standard
+    depends_on:
+      - etherpad-db
+    restart: unless-stopped
 
   etherpad-db:
     image: postgres:12
     container_name: etherpad-db
-    security_opt:
-      - no-new-privileges
-    mem_limit: "2048m"
-    cpus: "0.40"
-    pids_limit: 1024
     volumes:
       - etherpad-db:/var/lib/postgresql/data
     env_file: ./secrets/etherpad-db.secrets
-    restart: unless-stopped
     networks:
       - standard
+    restart: unless-stopped
 
   etherpad-week-app:
     image: registry.picasoft.net/pica-etherpad:1.8.4
     container_name: etherpad-week-app
     build: .
-    depends_on:
-      - etherpad-week-db
-    security_opt:
-      - no-new-privileges
-    mem_limit: "2048m"
-    cpus: 0.6
-    pids_limit: 1024
     env_file: ./secrets/etherpad-week-app.secrets
     volumes:
       - ./settings_week.json:/opt/etherpad-lite/settings.json
       - deleted-pads-week:/opt/etherpad-lite/deleted_pads
     labels:
+      traefik.http.routers.etherpad-week-app.entrypoints: websecure
+      traefik.http.routers.etherpad-week-app.rule: Host(`week.pad.picasoft.net`)
+      traefik.http.services.etherpad-week-app.loadbalancer.server.port: 8080
       traefik.enable: true
-      traefik.frontend.rule: "Host:week.pad.picasoft.net"
-      traefik.port: 8080
     environment:
       DB_HOST: "etherpad-week-db"
       LOGLEVEL: "INFO"
@@ -94,19 +78,16 @@ services:
       THEME: "colibris"
       TITLE: "Picapad Hebdo"
       TRUST_PROXY: "true"
-    restart: unless-stopped
+    depends_on:
+      - etherpad-week-db
     networks:
-      - docker_default
+      - proxy
       - week
+    restart: unless-stopped
 
   etherpad-week-db:
     image: postgres:12
     container_name: etherpad-week-db
-    security_opt:
-      - no-new-privileges
-    mem_limit: "2048m"
-    cpus: "0.40"
-    pids_limit: 1024
     volumes:
       - weekpad-db:/var/lib/postgresql/data
     env_file: ./secrets/etherpad-week-db.secrets
diff --git a/pica-grafana-prom/docker-compose.yml b/pica-grafana-prom/docker-compose.yml
index 02baa356a63b36e05c783e7ccfc2bcd2783c052e..08c98392b97cb7377604bf4eba1247054158ca61 100644
--- a/pica-grafana-prom/docker-compose.yml
+++ b/pica-grafana-prom/docker-compose.yml
@@ -2,8 +2,8 @@ version: '3.7'
 
 networks:
   metrics:
-  docker_default:
-    name: docker_default
+  proxy:
+    external: true
 
 volumes:
   grafana:
@@ -27,11 +27,12 @@ services:
       - GF_AUTH_LDAP_ALLOW_SIGN_UP=false
     env_file: ./secrets/grafana.secrets
     labels:
-      - "traefik.frontend.rule=Host:grafana.picasoft.net"
-      - "traefik.port=3000"
-      - "traefik.enable=true"
+      traefik.http.routers.grafana.entrypoints: websecure
+      traefik.http.routers.grafana.rule: Host(`grafana.picasoft.net`)
+      traefik.http.services.grafana.loadbalancer.server.port: 3000
+      traefik.enable: true
     networks:
-      - docker_default
+      - proxy
       - metrics
     restart: unless-stopped
 
diff --git a/pica-graphbot/config.json b/pica-graphbot/config.json
index b45218ae08841cfdb3e0266a73efe582bffe8966..e984a254cae25a0dcb08ed1a323045e84b74f58a 100644
--- a/pica-graphbot/config.json
+++ b/pica-graphbot/config.json
@@ -7,7 +7,7 @@
 			"url": "pica01.picasoft.net",
 			"port": 2376,
 			"exclude": [],
-			"default_network": "docker_default",
+			"default_network": "proxy",
 			"tls_config":
 			{
 				"ca_cert": "auth/pica01/ca.pem",
@@ -20,7 +20,7 @@
 			"url": "pica02.picasoft.net",
 			"port": 2376,
 			"exclude": [],
-			"default_network": "docker_default",
+			"default_network": "proxy",
 			"tls_config":
 			{
 				"ca_cert": "auth/pica02/ca.pem",
@@ -33,7 +33,7 @@
 			"url": "pica01-test.picasoft.net",
 			"port": 2376,
 			"exclude": [],
-			"default_network": "docker_default",
+			"default_network": "proxy",
 			"tls_config":
 			{
 				"ca_cert": "auth/pica01-test/ca.pem",
@@ -44,7 +44,7 @@
 		{
 			"name": "monitoring",
 			"url": "localhost",
-			"default_network": "docker_default"
+			"default_network": "proxy"
 		}
 	],
   "color_scheme": {
diff --git a/pica-lufi/docker-compose.yml b/pica-lufi/docker-compose.yml
index 6f50d31c6a3a0f931fd39c958dbab795c8b7d9d6..9cfd2878134844762ef20cb85caad81f7f7eb7f5 100644
--- a/pica-lufi/docker-compose.yml
+++ b/pica-lufi/docker-compose.yml
@@ -6,7 +6,7 @@ volumes:
   lufi-files:
 
 networks:
-  docker_default:
+  proxy:
     external: true
   lufi:
 
@@ -22,11 +22,12 @@ services:
       - lufi-files:/lufi/files
       - ./lufi.conf:/lufi/lufi.conf
     networks:
-      - docker_default
+      - proxy
       - lufi
     labels:
-      traefik.frontend.rule: Host:drop.picasoft.net
-      traefik.port: 8081
+      traefik.http.routers.lufi.entrypoints: websecure
+      traefik.http.routers.lufi.rule: Host(`drop.picasoft.net`)
+      traefik.http.services.lufi.loadbalancer.server.port: 8081
       traefik.enable: true
     env_file:
       - ./secrets/lufi.secrets
diff --git a/pica-mail/docker-compose.yml b/pica-mail/docker-compose.yml
index 6aed58883b5cf3823eb8fe7b6e1a44345426d923..9949f622d89ffeba860fa0fd1c8e66bc4947b96a 100644
--- a/pica-mail/docker-compose.yml
+++ b/pica-mail/docker-compose.yml
@@ -3,7 +3,7 @@ version: "3.7"
 networks:
   mail:
     name: pica-mail
-  docker_default:
+  proxy:
     external: true
 
 volumes:
@@ -44,7 +44,7 @@ services:
       - "587:587"
     networks:
       - mail
-      - docker_default
+      - proxy
     volumes:
       - mail-mta-log:/var/log
       #doit contenir selecteur.domaine.rsa
@@ -85,8 +85,7 @@ services:
       #prefixe DKIM, utilise pour identifier la clef
       DKIM_SELECTOR: janv2019
     labels:
-      traefik.frontend.rule: Host:mail.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.pica-mail-mta.rule: Host(`mail.picasoft.net`)
       traefik.enable: true
       tls-certs-monitor.enable: true
       tls-certs-monitor.action: restart
diff --git a/pica-mattermost/docker-compose.yml b/pica-mattermost/docker-compose.yml
index 5f66f8f384daa7649f44274765c76eb8ee687de4..58d07ec5b1dab7c02578d5e0cf153c638c301742 100644
--- a/pica-mattermost/docker-compose.yml
+++ b/pica-mattermost/docker-compose.yml
@@ -1,8 +1,8 @@
-version : "2.4"
+version : "3.7"
 networks:
-  docker_default:
+  proxy:
     external: true
-    name: "docker_default"
+  mattermost:
 
 volumes:
   mattermost-config:
@@ -30,12 +30,13 @@ services:
       - MM_SITEURL=https://team.picasoft.net
     env_file: ./secrets/mattermost-db.secrets
     labels:
-      - "traefik.frontend.rule=Host:team.picasoft.net"
-      - "traefik.port=8000"
-      - "traefik.frontend.passHostHeader=true"
-      - "traefik.enable=true"
+      traefik.http.routers.mattermost-app.entrypoints: websecure
+      traefik.http.routers.mattermost-app.rule: Host(`team.picasoft.net`)
+      traefik.http.services.mattermost-app.loadbalancer.server.port: 8000
+      traefik.enable: true
     networks:
-      - docker_default
+      - proxy
+      - mattermost
     depends_on:
       - mattermost-db
     restart: unless-stopped
@@ -48,5 +49,5 @@ services:
       - /etc/localtime:/etc/localtime:ro
     env_file: ./secrets/mattermost-db.secrets
     networks:
-      - docker_default
+      - mattermost
     restart: unless-stopped
diff --git a/pica-metrics-bot/docker-compose.yml b/pica-metrics-bot/docker-compose.yml
index 9755a65c2d295848403d786e2179304e5272d65a..1475f906cf16c4ac4f527c4507db6b2ccfa7fea8 100644
--- a/pica-metrics-bot/docker-compose.yml
+++ b/pica-metrics-bot/docker-compose.yml
@@ -5,7 +5,7 @@ volumes:
     name: influxdb-services
 
 networks:
-  docker_default:
+  proxy:
     external: true
   metrics:
 
@@ -36,10 +36,11 @@ services:
         - INFLUXDB_REPORTING_DISABLED=true
       env_file: ./secrets/influxdb.secrets
       labels:
-        traefik.frontend.rule: "Host:influxdb.picasoft.net"
-        traefik.port: 8086
-        traefik.enable: true
+      traefik.http.routers.influxdb-services.entrypoints: websecure
+      traefik.http.routers.influxdb-services.rule: Host(`influxdb.picasoft.net`)
+      traefik.http.services.influxdb-services.loadbalancer.server.port: 8086
+      traefik.enable: true
       networks:
         - metrics
-        - docker_default
+        - proxy
       restart: always
diff --git a/pica-mumble-web/docker-compose.yml b/pica-mumble-web/docker-compose.yml
index 47e266a7a10a1c99a5a8c8f469ea72a1f20f46d6..f035b82239c424ff8e656748c1119a2e86341470 100644
--- a/pica-mumble-web/docker-compose.yml
+++ b/pica-mumble-web/docker-compose.yml
@@ -1,8 +1,7 @@
-version: "2.4"
+version: "3.7"
 networks:
-  docker_default:
+  proxy:
     external: true
-    name: "docker_default"
 
 services:
   mumble-web:
@@ -12,12 +11,12 @@ services:
     environment:
       MUMBLE_SERVER: "voice.picasoft.net:64738"
     networks:
-      - docker_default
+      - proxy
     volumes:
       - ./config.json:/home/node/dist/config.local.js
     labels:
-      - "traefik.frontend.rule=Host:voice.picasoft.net"
-      - "traefik.port=8080"
-      - "traefik.frontend.passHostHeader=true"
-      - "traefik.enable=true"
+      traefik.http.routers.mumble-web.entrypoints: websecure
+      traefik.http.routers.mumble-web.rule: Host(`voice.picasoft.net`)
+      traefik.http.services.mumble-web.loadbalancer.server.port: 8080
+      traefik.enable: true
     restart: unless-stopped
diff --git a/pica-murmur/docker-compose.yml b/pica-murmur/docker-compose.yml
index d42e2cf8615d3c7c8e941b5cc11b9a9cb3b3f066..1cbb5cd8049c8785d0408cc95f19eaf000da639e 100644
--- a/pica-murmur/docker-compose.yml
+++ b/pica-murmur/docker-compose.yml
@@ -1,8 +1,7 @@
-version: "2.4"
+version: "3.7"
 networks:
-  docker_default:
+  proxy:
     external: true
-    name: "docker_default"
 
 volumes:
   murmur-data:
@@ -23,12 +22,13 @@ services:
       - murmur-data:/data
       - /DATA/docker/certs/voice.picasoft.net/:/certs
     networks:
-      - docker_default
+      - proxy
     labels:
-      - "traefik.enable=true"
-      - "traefik.port=8000"
-      - "traefik.frontend.rule=Host:voice.picasoft.net;Path:/metrics"
-      - "tls-certs-monitor.enable=true"
-      - "tls-certs-monitor.action=kill:SIGUSR1"
-      - "tls-certs-monitor.owner=103"
+      traefik.http.routers.murmur.entrypoints: websecure
+      traefik.http.routers.murmur.rule: Host(`voice.picasoft.net`) && Path(`/metrics`)
+      traefik.http.services.murmur.loadbalancer.server.port: 8000
+      traefik.enable: true
+      tls-certs-monitor.enable: true
+      tls-certs-monitor.action: kill:SIGUSR1
+      tls-certs-monitor.owner: 103
     restart: unless-stopped
diff --git a/pica-nextcloud/cet/docker-compose.yml b/pica-nextcloud/cet/docker-compose.yml
index 121853273c12f837612fc5ce562c47682c8a69d9..8ed5502a79ba9f19564b68188678fdda5fe5c8aa 100644
--- a/pica-nextcloud/cet/docker-compose.yml
+++ b/pica-nextcloud/cet/docker-compose.yml
@@ -2,7 +2,7 @@ version: '3.7'
 networks:
   nextcloud_cet:
     name: nextcloud_cet
-  docker_default:
+  proxy:
     external: true
 
 volumes:
@@ -34,11 +34,17 @@ services:
       - ./nginx.conf:/etc/nginx/nginx.conf:ro
     env_file: ./secrets/cloudcet.secrets
     labels:
-      - "traefik.frontend.rule=Host:cloudcet.picasoft.net"
-      - "traefik.port=80"
-      - "traefik.enable=true"
+      traefik.http.routers.cloudcet.entrypoints: websecure
+      traefik.http.routers.cloudcet.rule: Host(`cloudcet.picasoft.net`)
+      traefik.http.services.cloudcet.loadbalancer.server.port: 80
+      traefik.enable: true
+      # https://docs.nextcloud.com/server/16/admin_manual/configuration_server/reverse_proxy_configuration.html
+      traefik.http.routers.cloudcet.middlewares: cloudcet@docker
+      traefik.http.middlewares.cloudcet.redirectregex.permanent: true
+      traefik.http.middlewares.cloudcet.redirectregex.regex: ^/.well-known/(card|cal)dav
+      traefik.http.middlewares.cloudcet.redirectregex.replacement: /remote.php/dav/
     networks:
-      - docker_default
+      - proxy
       - nextcloud_cet
     depends_on:
       - cloudcet
diff --git a/pica-nextcloud/pica/docker-compose.yml b/pica-nextcloud/pica/docker-compose.yml
index 858886b484741a9818940b03b32c50bb8fbdce43..1ed1cc29da8af7e26e927838de248f728bd59c52 100644
--- a/pica-nextcloud/pica/docker-compose.yml
+++ b/pica-nextcloud/pica/docker-compose.yml
@@ -8,8 +8,8 @@ volumes:
 
 networks:
   nextcloud:
-  docker_default:
-    name: docker_default
+  proxy:
+    external: true
 
 services:
   nextcloud-app:
@@ -38,15 +38,17 @@ services:
       - nextcloud-app
     networks:
       - nextcloud
-      - docker_default
+      - proxy
     labels:
-      - "traefik.frontend.rule=Host:cloud.picasoft.net"
-      - "traefik.port=80"
-      - "traefik.enable=true"
+      traefik.http.routers.nextcloud-web.entrypoints: websecure
+      traefik.http.routers.nextcloud-web.rule: Host(`cloud.picasoft.net`)
+      traefik.http.services.nextcloud-web.loadbalancer.server.port: 80
+      traefik.enable: true
       # https://docs.nextcloud.com/server/16/admin_manual/configuration_server/reverse_proxy_configuration.html
-      - "traefik.frontend.redirect.permanent=true"
-      - "traefik.frontend.redirect.regex=https://(.*)/.well-known/(card|cal)dav"
-      - "traefik.frontend.redirect.replacement=https://$$1/remote.php/dav/"
+      traefik.http.routers.nextcloud-web.middlewares: nextcloud-web@docker
+      traefik.http.middlewares.nextcloud-web.redirectregex.permanent: true
+      traefik.http.middlewares.nextcloud-web.redirectregex.regex: ^/.well-known/(card|cal)dav
+      traefik.http.middlewares.nextcloud-web.redirectregex.replacement: /remote.php/dav/
     restart: unless-stopped
 
   nextcloud-db:
diff --git a/pica-nginx/README.md b/pica-nginx/README.md
index 361ccca71cf8b567e146cc12ffb8b11519cb9fe6..c2b93dd67dd9c3b29934b34b1427053d2fc8b6cc 100644
--- a/pica-nginx/README.md
+++ b/pica-nginx/README.md
@@ -33,13 +33,14 @@ mon_site:
   volumes:
     - mon_site:/var/www/html
   labels:
-    traefik.frontend.rule: Host:mon_site.picasoft.net
-    traefik.port: 80
+    traefik.http.routers.mon_site.entrypoints: websecure
+    traefik.http.routers.mon_site.rule: Host(`mon_site.picasoft.net`)
+    traefik.http.services.mon_site.loadbalancer.server.port: 80
     traefik.enable: true
   environment:
     AUTOINDEX: true
   networks:
-    - docker_default
+    - proxy
   restart: unless-stopped
 ```
 
diff --git a/pica-nginx/docker-compose.yml b/pica-nginx/docker-compose.yml
index da771c665239e66461315230eaab9cb4d7d98dcb..f56fe1c8bfcc49ded7c57448a07ada24b8507daa 100644
--- a/pica-nginx/docker-compose.yml
+++ b/pica-nginx/docker-compose.yml
@@ -15,7 +15,7 @@ volumes:
     name: stiegler
 
 networks:
-  docker_default:
+  proxy:
     external: true
 
 x-image-name: &NGINX_IMAGE
@@ -29,11 +29,12 @@ services:
     volumes:
       - website:/var/www/html
     labels:
-      traefik.frontend.rule: Host:www.picasoft.net,picasoft.net
-      traefik.port: 80
+      traefik.http.routers.website.entrypoints: websecure
+      traefik.http.routers.website.rule: Host(`www.picasoft.net`, `picasoft.net`)
+      traefik.http.services.website.loadbalancer.server.port: 80
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
 
   doc:
@@ -43,11 +44,12 @@ services:
     volumes:
       - doc:/var/www/html
     labels:
-      traefik.frontend.rule: Host:doc.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.doc.entrypoints: websecure
+      traefik.http.routers.doc.rule: Host(`doc.picasoft.net`)
+      traefik.http.services.doc.loadbalancer.server.port: 80
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
 
   school:
@@ -57,11 +59,12 @@ services:
     volumes:
       - school:/var/www/html
     labels:
-      traefik.frontend.rule: Host:school.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.school.entrypoints: websecure
+      traefik.http.routers.school.rule: Host(`school.picasoft.net`)
+      traefik.http.services.school.loadbalancer.server.port: 80
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
 
   radio:
@@ -71,13 +74,14 @@ services:
     volumes:
       - radio:/var/www/html
     labels:
-      traefik.frontend.rule: Host:radio.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.radio.entrypoints: websecure
+      traefik.http.routers.radio.rule: Host(`radio.picasoft.net`)
+      traefik.http.services.radio.loadbalancer.server.port: 80
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
-    
+
   culture:
     container_name: culture
     image: *NGINX_IMAGE
@@ -85,13 +89,14 @@ services:
     volumes:
       - culture:/var/www/html
     labels:
-      traefik.frontend.rule: Host:culture.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.culture.entrypoints: websecure
+      traefik.http.routers.culture.rule: Host(`culture.picasoft.net`)
+      traefik.http.services.culture.loadbalancer.server.port: 80
       traefik.enable: true
     environment:
       AUTOINDEX: "true"
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
 
   stiegler:
@@ -101,9 +106,10 @@ services:
     volumes:
       - stiegler:/var/www/html
     labels:
-      traefik.frontend.rule: Host:stiegler.picasoft.net
-      traefik.port: 80
+      traefik.http.routers.stiegler.entrypoints: websecure
+      traefik.http.routers.stiegler.rule: Host(`stiegler.picasoft.net`)
+      traefik.http.services.stiegler.loadbalancer.server.port: 80
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
     restart: unless-stopped
diff --git a/pica-openldap/bootstrap/ldif/init.ldif b/pica-openldap/bootstrap/ldif/init.ldif
index 23e37b2de745eade0680d464d66edfe6a4539d19..4343c3bd937ceaf5ba2cc688f17e813182bb96a9 100644
--- a/pica-openldap/bootstrap/ldif/init.ldif
+++ b/pica-openldap/bootstrap/ldif/init.ldif
@@ -35,8 +35,7 @@ gidNumber: 502
 objectClass: posixGroup
 objectClass: top
 cn: representant
-description: Groupe secondaire. Les personnes dans ce groupes peuvent accéder aux services restreints aux membres (exemple : Cloud...)
-memberUid:
+description: Groupe primaire. Les personnes dans ce groupe ont un accès basique aux machines et peuvent accéder à des services restreints aux membres (Cloud, édition Wiki...)
 
 dn: cn=representant,ou=Groups,{{ LDAP_BASE_DN }}
 gidNumber: 503
diff --git a/pica-openldap/docker-compose.yml b/pica-openldap/docker-compose.yml
index 1882ea54aedd24d57b0b8e85eec58ca888293759..ce93ea0a910cf2f08ee531c7a41057fdf36e8eb2 100644
--- a/pica-openldap/docker-compose.yml
+++ b/pica-openldap/docker-compose.yml
@@ -16,7 +16,7 @@ services:
     env_file:
       - ./secrets/pica-openldap.secrets
     labels:
-      traefik.frontend.rule: "Host:ldap.picasoft.net"
+      traefik.http.routers.ldap.rule: Host(`ldap.picasoft.net`)
       traefik.enable: true
       tls-certs-monitor.enable: true
       tls-certs-monitor.action: "restart"
diff --git a/pica-plume/docker-compose.yml b/pica-plume/docker-compose.yml
index cce72fbf10f44658eeae490517540b0ce43c05be..4f8acc3534e6c07b82400678193dae89e737ac29 100644
--- a/pica-plume/docker-compose.yml
+++ b/pica-plume/docker-compose.yml
@@ -11,7 +11,7 @@ volumes:
     name: plume_first_launch
 
 networks:
-  docker_default:
+  proxy:
     external: true
   plume:
     name: plume
@@ -34,12 +34,13 @@ services:
       - searchidx:/app/search_index
       - first-launch:/firstlaunch
     labels:
-      traefik.frontend.rule: "Host:blog.picasoft.net"
+      traefik.http.routers.blog.entrypoints: websecure
+      traefik.http.routers.blog.rule: Host(`blog.picasoft.net`)
+      traefik.http.services.blog.loadbalancer.server.port: 7878
       traefik.enable: true
-      traefik.port: 7878
     networks:
       - plume
-      - docker_default
+      - proxy
     depends_on:
       - blog-db
     restart: unless-stopped
diff --git a/pica-registry/docker-compose.yml b/pica-registry/docker-compose.yml
index 6ba2be28667dbc03598e81bf008ff34bc3175e94..9609cd9a501e31fee0b0e607b4b474f0373cd56e 100644
--- a/pica-registry/docker-compose.yml
+++ b/pica-registry/docker-compose.yml
@@ -1,8 +1,8 @@
 version: '3.7'
 
 networks:
-  docker_default:
-    name: docker_default
+  proxy:
+    external: true
 
 volumes:
   registry:
@@ -18,12 +18,13 @@ services:
       REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
       REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
     networks:
-      - docker_default
+      - proxy
     volumes:
       - registry:/var/lib/registry
       - ./auth.secrets:/auth/htpasswd
     labels:
-      traefik.frontend.rule: Host:registry.picasoft.net
-      traefik.port: 5000
+      traefik.http.routers.registry.entrypoints: websecure
+      traefik.http.routers.registry.rule: Host(`registry.picasoft.net`)
+      traefik.http.services.registry.loadbalancer.server.port: 5000
       traefik.enable: true
     restart: unless-stopped
diff --git a/pica-traefik/README.md b/pica-traefik/README.md
index 0544aa4a2f67adb20a15621f8056acdc35e103ce..d3c67df35de51f8fd5d246a2032ffedd3e2244ca 100644
--- a/pica-traefik/README.md
+++ b/pica-traefik/README.md
@@ -7,36 +7,28 @@ Ce service doit être lancé sur l'ensemble des machines de l'infrastructure.
 
 ### Configuration
 
-La configuration a lieu dans le fichier [traefik.toml](./traefik.toml).
+La configuration a lieu dans les fichiers [traefik.toml](./traefik.toml) et [traefik_dynamic.toml](./traefik_dynamic.toml).
 Notez que toute modification dans ce fichier impactera l'ensemble des machines, puisque le même fichier est utilisé pour l'ensemble des machines.
 
 À des fins de tests, il peut être modifié localement sur les machines, mais doit toujours rester synchronisé avec ce dépôt à long terme.
 
 Pour la génération des certificats, Traefik utilise Let's Encrypt. Il n'y a aucune configuration à faire de ce côté. Attention, le nombre de certificats générables est limité à 50 par semaine.
 
-Si on lance plein de conteneurs de tests, on utilisera temporairement [l'environnement de qualification](https://letsencrypt.org/fr/docs/staging-environment/) de Let's Encrypt, en ajoutant la directive `caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"` sous la section `[acme]`.
+Si on lance plein de conteneurs de tests, on utilisera temporairement [l'environnement de qualification](https://letsencrypt.org/fr/docs/staging-environment/) de Let's Encrypt, en ajoutant la directive `caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"` sous la section `[certificatesResolvers.letsencrypt.acme]`.
 
 ### Lancement
 
-Assurez-vous que le dossier `/DATA/docker/traefik/certs` existe.
-C'est dans ce dossier que seront conservés tous les certificats générés par Traefik.
+Au premier lancement, assurez-vous que :
+* Le dossier `/DATA/docker/traefik/certs` existe
+* Créez un fichier `acme.json` à l'intérieur
+* Changez son propriétaire à `root`
+* Changez ses permissions à `600`
+
+C'est dans ce fichier que seront conservés tous les certificats générés par Traefik.
 
 ### Mise à jour
 
 Il suffit de mettre à jour le tag de l'image dans Compose.
-Attention, Traefik v2 introduit énormément de changements et [nous ne sommes pas certains](https://wiki.picasoft.net/doku.php?id=technique:adminsys:migration-traefik-v2) de la manière d'effectuer la migration.
-
-Aussi, Traefik v1.6 est utilisé pour tenterd d'éviter un bug introduit dans la 1.7, qui rend certains services redémarrés inaccessibles (voir [cette discussion](https://team.picasoft.net/picasoft/pl/66aorsxhtffrjytyhnecn436wa)).
-
-Avant toute mise à jour, il faudra discuter avec l'équipe technique et modifier ce README le cas échéant.
-
-### Todo
-
-*Voir si on peut passer Traefik en "host" au niveau du réseau pour qu'il ait accès à tous les réseaux* :
-https://kanban.picasoft.net/b/7fCn765LCNGraBhxA/team-technique-picasoft/kjvc3iw2pFvszCTcR
-
-Actuellement, Traefik est dans le réseau `docker_default` sur toutes les machines, et les conteneurs souhaitant être accessibles via Traefik doivent être explicitement dans ce réseau.
-
-Ceci induit une complexité supplémentaire au niveau des fichiers Compose.
+Lire la documentation [sur les mises à jour mineures](https://docs.traefik.io/v2.2/migration/v2/) pour voir s'il y a des opérations à effectuer ou des options dépréciées.
 
-Il serait peut être bon de permettre à Traefik d'accéder à tous les réseaux et de supprimer énormément de directives "inutiles" dans les Compose.
+La mise à jour vers Traefik v2 a été effectuée ; quelques détails sont à consulter [sur le wiki](https://wiki.picasoft.net/doku.php?id=technique:adminsys:migration-traefik-v2).
diff --git a/pica-traefik/docker-compose.yml b/pica-traefik/docker-compose.yml
index daaf9802d24f03b53766fa67ec286b8a2a18522f..d4a139e9324c18bbb0c9819548542b547facdc6d 100644
--- a/pica-traefik/docker-compose.yml
+++ b/pica-traefik/docker-compose.yml
@@ -1,18 +1,22 @@
 version: '3.7'
 
+networks:
+  proxy:
+    name: 'proxy'
+
 services:
   traefik:
-  container_name: traefik
-  # DO NOT UPGRADE
-  # SEE THIS BEFORE AND DISCUSS : https://team.picasoft.net/picasoft/pl/66aorsxhtffrjytyhnecn436wa
-  image: traefik:1.6.6
-  ports:
-    - "80:80"
-    # Uncomment to expose the web interface. Warning : do not use without setting a password in traefik.toml
-    #- "8080:8080"
-    - "443:443"
-  volumes:
-    - /var/run/docker.sock:/var/run/docker.sock
-    - ./traefik.toml:/traefik.toml
-    - /DATA/docker/traefik/certs:/certs
-  restart: always
+    image: traefik:2.3
+    container_name: traefik
+    ports:
+      - 80:80
+      - 443:443
+    volumes:
+      - /etc/localtime:/etc/localtime:ro
+      - /var/run/docker.sock:/var/run/docker.sock
+      - ./traefik.toml:/traefik.toml
+      - ./traefik_dynamic.toml:/traefik_dynamic.toml
+      - /DATA/docker/traefik/certs:/certs
+    networks:
+      - proxy
+    restart: unless-stopped
diff --git a/pica-traefik/traefik.toml b/pica-traefik/traefik.toml
index 351461989e113a1faf7e831ca614f1a7922cfd56..a154bb578889e9e2b85f2f512cfeb4e80de4e72f 100644
--- a/pica-traefik/traefik.toml
+++ b/pica-traefik/traefik.toml
@@ -1,35 +1,40 @@
-logLevel = "INFO"
-debug = true
-defaultEntryPoints = ["http", "https"]
+[global]
+  sendAnonymousUsage = false
+  checkNewVersion = true
 
-[docker]
-endpoint = "unix:///var/run/docker.sock"
-watch = true
-exposedbydefault = false
+[entryPoints]
+  [entryPoints.web]
+    address = ":80"
+    [entryPoints.web.http.redirections.entryPoint]
+      to = "websecure"
+      scheme = "https"
+  [entryPoints.websecure]
+    address = ":443"
+    [entryPoints.websecure.http]
+      middlewares = ["hardening@file", "compression@file"]
+      [entryPoints.websecure.http.tls]
+        certResolver = "letsencrypt"
+        options = "tls12@file"
 
-[api]
 
-[entryPoints]
- [entryPoints.http]
-  address = ":80"
-  compress = false
-  [entryPoints.http.redirect]
-   entryPoint = "https"
- [entryPoints.https]
-  address = ":443"
-  compress = false
-  [entryPoints.https.tls]
-   # Accept only TLS1.1 and 1.2
-   MinVersion = "VersionTLS11"
-   # Accept all ciphers excepting TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA and TLS_RSA_WITH_3DES_EDE_CBC_SHA
-   # CipherSuites = ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_256_CBC_SHA" ]
-   # Keep only ECDHE :
-   CipherSuites = ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" ]
+[providers]
+  providersThrottleDuration = "2s"
+  [providers.docker]
+    watch = true
+    endpoint = "unix:///var/run/docker.sock"
+    exposedByDefault = false
+    network = "proxy"
+  [providers.file]
+    filename = "/traefik_dynamic.toml"
+    watch = true
+
+[log]
+  level = "INFO"
 
-[acme]
- email = "picasoft@assos.utc.fr"
- storage = "/certs/acme.json"
- entryPoint = "https"
- onHostRule = true
- [acme.httpChallenge]
-  entryPoint = "http"
+[certificatesResolvers]
+  [certificatesResolvers.letsencrypt]
+    [certificatesResolvers.letsencrypt.acme]
+      email = "picasoft@assos.utc.fr"
+      storage = "/certs/acme.json"
+      [certificatesResolvers.letsencrypt.acme.httpChallenge]
+        entryPoint = "web"
diff --git a/pica-traefik/traefik_dynamic.toml b/pica-traefik/traefik_dynamic.toml
new file mode 100644
index 0000000000000000000000000000000000000000..398f83d557cb2ea3f9ac04233502a4d8292181e2
--- /dev/null
+++ b/pica-traefik/traefik_dynamic.toml
@@ -0,0 +1,28 @@
+[tls.options]
+  [tls.options.tls12]
+    minVersion = "VersionTLS12"
+    cipherSuites = [
+      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+      "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+      "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
+      "TLS_AES_256_GCM_SHA384",
+      "TLS_CHACHA20_POLY1305_SHA256"
+    ]
+    curvePreferences = ["CurveP521","CurveP384"]
+
+[http]
+  [http.middlewares.hardening.headers]
+    addVaryHeader = true
+    browserXssFilter = true
+    contentTypeNosniff = true
+    forceSTSHeader = true
+    frameDeny = true
+    stsIncludeSubdomains = true
+    stsPreload = true
+    customFrameOptionsValue = "SAMEORIGIN"
+    referrerPolicy = "same-origin"
+    featurePolicy = "vibrate 'self'"
+    stsSeconds = 315360000
+
+  [http.middlewares.compression.compress]
+    excludedContentTypes = ["text/event-stream"]
diff --git a/pica-uploads/docker-compose.yml b/pica-uploads/docker-compose.yml
index ea307aa8ddbe7421b5a64b4359ac5f64ad106569..6c33d43f7f8a6c4a70a23203a6c929e315672004 100644
--- a/pica-uploads/docker-compose.yml
+++ b/pica-uploads/docker-compose.yml
@@ -2,11 +2,11 @@ version: "3.7"
 
 volumes:
   uploads:
-    external: true
+    name: uploads
 
 networks:
   sftp:
-  docker_default:
+  proxy:
     external: true
 
 services:
@@ -28,9 +28,10 @@ services:
     volumes:
       - uploads:/var/www/html
     labels:
-      - "traefik.frontend.rule=Host:uploads.picasoft.net"
-      - "traefik.port=80"
-      - "traefik.enable=true"
-    restart: unless-stopped
+      traefik.http.routers.uploads.entrypoints: websecure
+      traefik.http.routers.uploads.rule: Host(`uploads.picasoft.net`)
+      traefik.http.services.uploads.loadbalancer.server.port: 80
+      traefik.enable: true
     networks:
-      - docker_default
+      - proxy
+    restart: unless-stopped
diff --git a/pica-wekan/docker-compose.yml b/pica-wekan/docker-compose.yml
index 561b520122e819299685a4e54e4300dc34a9d320..ba783ce75dbaaea00cd0d4ac4fad817dc2494147 100644
--- a/pica-wekan/docker-compose.yml
+++ b/pica-wekan/docker-compose.yml
@@ -4,10 +4,10 @@ volumes:
   wekan:
 
 networks:
-  docker_default:
+  proxy:
     external: true
   wekan:
-    name: "wekan"
+    name: wekan
 
 services:
   wekan-db:
@@ -40,11 +40,12 @@ services:
     depends_on:
       - wekan-db
     labels:
-      traefik.frontend.rule: Host:kanban.picasoft.net
-      traefik.port: 8080
+      traefik.http.routers.wekan-app.entrypoints: websecure
+      traefik.http.routers.wekan-app.rule: Host(`kanban.picasoft.net`)
+      traefik.http.services.wekan-app.loadbalancer.server.port: 8080
       traefik.enable: true
     networks:
-      - docker_default
+      - proxy
       - wekan
     restart: unless-stopped
 
@@ -55,9 +56,10 @@ services:
     environment:
       - KANBAN_URL=https://kanban.picasoft.net
     networks:
-      - docker_default
+      - proxy
     labels:
+      traefik.http.routers.wekan-filter-hooks.entrypoints: websecure
+      traefik.http.routers.wekan-filter-hooks.rule: Host(`kanban.picasoft.net`) && Path('/forward_hooks')
+      traefik.http.services.wekan-filter-hooks.loadbalancer.server.port: 5000
       traefik.enable: true
-      traefik.port: 5000
-      traefik.frontend.rule: Host:kanban.picasoft.net;Path:/forward_hooks
     restart: unless-stopped
diff --git a/template/docker-compose.yml b/template/docker-compose.yml
index c4fbd859d9959b1881a61385dbdc044915f74db1..a9a1d4b77528d71c740f9a71c34bc6840a5e5fe0 100644
--- a/template/docker-compose.yml
+++ b/template/docker-compose.yml
@@ -23,7 +23,7 @@ networks:
   app:
   # This is the reverse-proxy default network : put all services
   # that need to be served via Traefik in this network
-  docker_default:
+  proxy:
     external: true
 
 services:
@@ -48,10 +48,10 @@ services:
     # entrypoint, for exemple.
     init: true
     # If the container has to be reached from
-    # the Internet, put in docker_default
+    # the Internet, put in proxy
     # Otherwise, just in its own network
     networks:
-      - docker_default
+      - proxy
       - app
     volumes:
       # Mount the Docker Volume in the container
@@ -72,10 +72,12 @@ services:
     # redirected to this container.
     # Change the port to the exposed port of the
     # container.
+    # Replace ".app" by the container name.
     labels:
       traefik.enable: true
-      traefik.frontend.rule: "Host:app.picasoft.net"
-      traefik.port: 80
+      traefik.http.routers.app.entrypoints: websecure
+      traefik.http.routers.app.rule: Host(`app.picasoft.net`)
+      traefik.http.services.app.loadbalancer.server.port: 80
     # If the service has a database,
     # tell Compose that it depends on it (i.e.)
     # should be launched if the service is launched