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()