---
title: Traefik KOP
created: 2026-06-06
updated: 2026-06-06
type: app
tags: [catalogue, reverse-proxy, traefik, multi-host, redis, docker, go]
confidence: high
contested: false
sources: [https://selfh.st/apps/?tag=Reverse+Proxy, https://github.com/jittering/traefik-kop]
---

# 🚦 Traefik KOP

> **Agent de découverte multi-host pour Traefik : synchronise les containers Docker distants via Redis**. Résout le problème du cluster Docker **sans Swarm/K8s** : un seul Traefik public fait face à Internet, des agents sur chaque node exposent leurs services.

## 📋 Informations Générales

| Champ | Valeur |
| :--- | :--- |
| **Site web** | (GitHub uniquement) |
| **GitHub** | [jittering/traefik-kop](https://github.com/jittering/traefik-kop) |
| **License** | MIT |
| **Langage** | Go (98.4 %) |
| **Étoiles GitHub** | 493 ⭐ |
| **Dernière MAJ** | 2026-05-11 (v0.20.1) |
| **Catégorie** | [[cat-reverse-proxy|Reverse Proxy]], Multi-host, Docker, Redis |

## 📝 Description

**Traefik KOP** (par Chetan Sarva, alias jittering) est un **agent de découverte Docker→Redis→Traefik** : il tourne sur **chaque host Docker** d'un cluster et **publie dans Redis** les labels Traefik de ses containers, pour qu'une **instance Traefik centrale** (unique, publique) puisse router le trafic vers le bon host via le **redis provider** de Traefik.

Le problème résolu : Traefik fonctionne nativement avec **Docker Swarm** ou **Kubernetes** pour la découverte multi-host. Mais en mode "**plain Docker**" multi-host (plusieurs machines, pas d'orchestrateur), il n'y a pas de mécanisme unifié. KOP apporte cette fonctionnalité avec **un binaire Go léger + Redis**.

**Caractéristiques principales** :

- ✅ **Léger** : un seul binaire Go (~15 MB) par host Docker distant
- ✅ **Même syntaxe** que le provider Docker de Traefik : labels standards
- ✅ **Redis backend** : source unique de vérité partagée
- ✅ **Compatible Sentinel** Redis (pour la HA)
- ✅ **Bind IP** configurable par service (`:8088` du container sur le bon host)
- ✅ **Détection auto** de l'IP de bind (interface réseau ou IP explicite)
- ✅ **CLI flags + env vars** (12-factor)
- ✅ **Healthcheck** intégré
- ✅ **Remplacement d'IP** customisable (utile en NAT / WireGuard)
- ✅ **Cross-platform** : Linux, ARM, FreeBSD

**Public cible** : administrateurs qui ont un **cluster Docker multi-host "artisanal"** (3-10 machines, pas envie de Swarm ni K8s) et qui veulent **un seul reverse proxy public** pour tout exposer avec des certs Let's Encrypt unifiés. KOP est cité comme **la** solution de référence pour ce cas d'usage (avec [[app-frp]] et des solutions type Consul).

## 🚀 Installation

### Architecture cible

```
                    Internet
                       │
                       ▼
                 ┌───────────┐
                 │  Traefik  │  (host public)
                 │  + Redis  │
                 └─────┬─────┘
                       │ (redis pub/sub)
            ┌──────────┼──────────┐
            ▼          ▼          ▼
       ┌────────┐ ┌────────┐ ┌────────┐
       │ Host A │ │ Host B │ │ Host C │
       │ traefik-kop │traefik-kop │traefik-kop
       │ + Docker    │+ Docker    │+ Docker
       └────────┘ └────────┘ └────────┘
```

### Sur le host Traefik public (host central)

```yaml
# docker-compose.yml
version: '3.8'
services:
  traefik:
    image: traefik:v3
    container_name: traefik
    restart: unless-stopped
    command:
      - "--providers.docker=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.redis=true"
      - "--providers.redis.endpoints=redis:6379"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    networks:
      - proxy

  redis:
    image: redis:7-alpine
    container_name: redis
    restart: unless-stopped
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - ./redis-data:/data
    networks:
      - proxy

networks:
  proxy:
    external: true
```

### Sur chaque host Docker distant

```yaml
# docker-compose.yml (sur host A, B, C...)
version: '3.8'
services:
  traefik-kop:
    image: ghcr.io/jittering/traefik-kop:latest
    container_name: traefik-kop
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - REDIS_ADDR=192.168.1.50:6379   # IP du host central
      - BIND_IP=192.168.1.75            # IP de CE host distant
      - KOP_HOSTNAME=host-a
      - VERBOSE=true
    networks:
      - proxy
```

### Exemple de service à exposer (sur host distant)

```yaml
# sur host A : service nginx
version: '3.8'
services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - "8088:80"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`nginx.example.com`)"
      - "traefik.http.routers.nginx.tls=true"
      - "traefik.http.routers.nginx.tls.certresolver=letsencrypt"
      - "traefik.http.services.nginx.loadbalancer.server.scheme=http"
      - "traefik.http.services.nginx.loadbalancer.server.port=8088"
```

> ⚠️ Le `traefik.http.services.X.loadbalancer.server.port` **doit** correspondre au port publié sur l'host distant (8088 ici), pas le port interne du container (80).

## ⚙️ Configuration Initiale

1. **Déployer Traefik + Redis** sur le host public (cf. bloc ci-dessus).
2. **Déployer `traefik-kop`** sur chaque host distant avec `REDIS_ADDR` pointant vers le Redis public.
3. **Ajouter des labels Traefik standards** sur les containers des hosts distants (comme s'ils étaient sur le host central).
4. **Tester** : `curl -H "Host: nginx.example.com" http://TRAEFIK_PUBLIC_IP/` doit répondre.

### Configuration avancée (ordre de précédence pour bind IP)

1. Label `kop.<service>.bind.ip` (per-service)
2. Label `kop.bind.ip` (global)
3. `traefik.docker.network` (auto-détection via réseau)
4. `--bind-ip` / `BIND_IP` env (global)
5. `--bind-interface` / `BIND_INTERFACE` (avec `network_mode: host`)
6. Auto-détection IP de l'host

## 🔄 Alternatives

### Open Source

- **Docker Swarm mode** — la voie "standard" multi-host Docker
- **Kubernetes + Traefik Ingress** — pour les gros déploiements
- **HashiCorp Consul** + Traefik provider — alternative à Redis
- **etcd** + Traefik provider — alternative à Redis
- **GloboDNS / PowerDNS** — pas vraiment comparable (DNS)
- **Traefik Pilot** (abandonné)
- [[app-frp]] — tunnel L4 multi-host (approche différente)

### Propriétaires (ce que Traefik KOP remplace)

- **Cloudflare Tunnel** (gratuit, gère multi-host)
- **Ngrok Enterprise** (multi-region)
- **Ngrok + Reserved domains**
- **Cloudflare Spectrum** (TCP/UDP)
- **Datadog Service Map** orienté observabilité
- **Pusher / Ably** (si usage realtime)

### Comparaison rapide

| Critère | Traefik KOP | Docker Swarm | Consul + Traefik |
| :--- | :--- | :--- | :--- |
| Orchestrateur requis | ❌ | ✅ Swarm | ❌ |
| Backend state | Redis | Raft (intégré) | Consul KV |
| Léger | ✅ (15 MB) | ❌ | ⚠️ |
| Complexité | ✅ Faible | ⚠️ Moyenne | ⚠️ Moyenne |
| Tolérance panne Redis | ❌ | n/a | ⚠️ |
| HA | Redis Sentinel | Natif (Raft) | Natif (Consul) |
| License | MIT | Apache-2.0 | MPL-2.0 |

**Verdict** : **Traefik KOP** pour les clusters **3-10 hosts** "à la main" qui ne veulent pas de Swarm/K8s. **Docker Swarm** si on accepte l'orchestrateur Docker natif. **Consul** pour qui a déjà l'écosystème HashiCorp.

## 🔐 Sécurité

- **Redis** : doit être sécurisé (mot de passe, ACL, TLS). Sans auth, n'importe qui peut injecter des routes dans Traefik.
- **Docker socket** : `traefik-kop` lit `/var/run/docker.sock` en RW → un container compromis peut **usurper** des routes. À monter en `ro` si possible (mais limité).
- **Bind IP** : ne pas mettre `0.0.0.0`, utiliser l'IP LAN explicite pour éviter l'exposition sur le WAN
- **Réseau Redis** : ne **jamais** exposer Redis sur Internet, VPN ou WireGuard entre les hosts
- **API Traefik** : désactiver le dashboard en production (`--api.insecure=false`) ou le mettre derrière auth
- **Rotation des credentials Redis** : possible, KOP recharge à chaud
- **Sentinel** : recommandé pour la HA (plusieurs instances Redis)
- ⚠️ **Pas d'auth par défaut** entre KOP et Traefik : tout repose sur la sécurité du réseau Redis

## 📚 Ressources

- [README officiel](https://github.com/jittering/traefik-kop)
- [Issue Traefik #7886 (sticky sessions)](https://github.com/traefik/traefik/issues/7886) — contexte du problème KOP résout
- [Forum Traefik sticky sessions](https://community.traefik.io/t/sticky-sessions-dont-work/1949)
- [Documentation Traefik providers](https://doc.traefik.io/traefik/providers/redis/)
- [Sponsor : ko-fi chetan](https://github.com/sponsors/chetan) — le dev principal

## Pages Liées

- [[cat-reverse-proxy]] — Catégorie Reverse Proxy
- [[app-traefik]] — Le reverse proxy central
- [[app-caddy]] — Alternative plus simple
- [[docker-swarm]] — Orchestration native Docker
- [[comparatif-reverse-proxy]] — Comparaison détaillée
- [[redis]] — Backend de découverte
