VPNSmith
self-host-vpnINFO

WireGuard dans Docker (2026) : la méthode propre pour s'auto-héberger avec docker-compose

Faire tourner WireGuard dans Docker correctement : linuxserver/wireguard vs wg-easy, le fichier docker-compose, les pièges NET_ADMIN et sysctl, la persistance, et quand un conteneur bat une install bare-metal.

Par Eric Gerard · Fondateur · VPNSmith - Spécialiste self-host VPN & VPS GDPR7 min de lecturePhoto via Unsplash

Transparence affiliation - Ce guide renvoie vers Contabo, l'hébergeur de VPS qu'il prend comme exemple. Une commande via notre lien nous rémunère sans surcoût pour vous. La configuration ci-dessous suit la documentation officielle de chaque image.

Faire tourner WireGuard dans Docker apporte ce qui rend les conteneurs utiles : un serveur que l'on monte, démonte, versionne et déplace vers un autre hôte en quelques minutes, sans aucun paquet installé sur la machine elle-même. Le hic : un conteneur VPN n'est pas un conteneur normal - il touche à la pile réseau du noyau, donc quelques flags sont non négociables. Bien réglés, un WireGuard conteneurisé est aussi rapide qu'en bare-metal. Mal réglés, le tunnel se connecte mais ne route rien, en silence.

Voici la méthode propre, façonnée pour la production.

Pas encore d'hôte ? Les exemples partent d'un VPS Cloud Contabo (lien affilié), dès 5,50 € par mois sur 24 mois (tarif relevé le 17 octobre 2026) : il tourne sous KVM, l'hôte a donc son propre noyau avec le module WireGuard intégré dont le conteneur dépend. Si vous préférez un hébergeur américain avec 30 jours satisfait ou remboursé, le VPS Basic d'Ultahost coûte 5,52 $ par mois sur 24 mois (1 Go de RAM, IPv4 dédiée, relevé le 21 octobre 2026), et ses VPS tournent eux aussi sous KVM (indiqué sur ultahost.com, relevé le 26 octobre 2026), donc le module noyau est bien là. Autre option : HostPapa Unmanaged VPS Lite (lien affilié) à 2,95 $ par mois sur un engagement de 3 ans, puis au tarif normal (1 cœur, 1 Go de RAM, 25 Go NVMe, accès root SSH, satisfait ou remboursé 30 jours, relevé le 28 octobre 2026).

D'abord, l'erreur classique sur « WireGuard dans Docker »

WireGuard est un module noyau. Quand vous « faites tourner WireGuard dans Docker », le chiffrement et le routage se passent toujours dans le noyau Linux de l'hôte - le conteneur ne porte que les outils userspace (wg, wg-quick) et votre configuration. C'est pourquoi il n'y a aucune pénalité de performance : le chemin des données n'entre jamais dans le conteneur.

Cela explique aussi les prérequis. Pour créer et gérer une interface réseau depuis un conteneur, celui-ci a besoin d'une capability réseau élevée (NET_ADMIN), et l'hôte doit être autorisé à forwarder les paquets (net.ipv4.ip_forward=1). Ce ne sont pas des options de durcissement - sans elles, le conteneur refuse de démarrer ou monte sans rien router.

Choisir son image : linuxserver/wireguard vs wg-easy

Deux images couvrent presque tous les cas :

  • linuxserver/wireguard - un serveur propre piloté par config. Vous définissez les peers via variables d'environnement ou en éditant des fichiers dans un dossier /config monté. Il génère configs clientes et QR codes au premier lancement. Idéal pour l'infrastructure-as-code, beaucoup de peers, ou pour committer votre setup dans un dépôt privé.
  • wg-easy - WireGuard plus un tableau de bord web. Créez et révoquez des peers depuis un navigateur, scannez les QR codes pour les téléphones, suivez le trafic par client en direct. Idéal pour quelques appareils et un onboarding rapide sans toucher au CLI. On le détaille de bout en bout - y compris le changement de mot de passe v14 - dans le guide complet wg-easy en auto-hébergement.

Les deux sont matures et largement utilisées. Le choix est tableau-de-bord-vs-fichiers, pas une question de qualité.

Le fichier docker-compose (wg-easy)

Vérification de version (25 octobre 2026) : cet exemple utilise les variables de wg-easy v14, il est donc épinglé sur l'image :14. wg-easy v15 (version actuelle 15.5.0) ne lit plus WG_HOST, PASSWORD_HASH ni WG_DEFAULT_DNS. Pour obtenir un fichier v15 en une minute, utilisez notre générateur docker-compose wg-easy.

Générez ici votre docker-compose.yml wg-easy v15

Indiquez l'adresse du serveur et la façon d'accéder au panneau : vous obtenez le fichier compose, le Caddyfile si besoin et les commandes d'installation.

01Décrivez votre serveur

Tout est généré dans votre navigateur. Rien de ce que vous saisissez, mot de passe compris, n'est envoyé à nos serveurs.

L'adresse à laquelle les clients WireGuard se connectent.

Comment accéderez-vous au panneau ?

Un enregistrement A pour ce nom doit pointer vers le serveur, ports 80 et 443 ouverts.

Sans installation automatique, ouvrez le panneau après le premier démarrage : l'assistant demande le compte administrateur, puis l'hôte et le port. Saisissez le même port UDP que ci-dessus.

02Copiez les fichiers

docker-compose.yml
# wg-easy v15 - generated on vpnsmith.com/en/tools/wg-easy-compose-generator
# Host: vpn.example.com - WireGuard port: 51820/udp - panel: https://wg.example.com

volumes:
  etc_wireguard:
  caddy_data:
  caddy_config:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:15
    container_name: wg-easy
    environment:
      - PORT=80
      - TRUSTED_PROXIES=10.42.42.43,fdcc:ad94:bacf:61a3::2b
    networks:
      wg:
        ipv4_address: 10.42.42.42
        ipv6_address: fdcc:ad94:bacf:61a3::2a
    volumes:
      - etc_wireguard:/etc/wireguard
      - /lib/modules:/lib/modules:ro
    ports:
      - "51820:51820/udp"   # WireGuard: the only port clients need
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv6.conf.all.forwarding=1
      - net.ipv6.conf.default.forwarding=1

  caddy:
    image: caddy:2-alpine
    container_name: caddy
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
    networks:
      wg:
        ipv4_address: 10.42.42.43
        ipv6_address: fdcc:ad94:bacf:61a3::2b
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    restart: unless-stopped

networks:
  wg:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 10.42.42.0/24
        - subnet: fdcc:ad94:bacf:61a3::/64
Caddyfile
wg.example.com {
	reverse_proxy wg-easy:80
}

03Lancez les commandes d'installation

install.sh
# 1. Pare-feu : SSH d'abord, puis le port WireGuard
sudo ufw allow OpenSSH
sudo ufw allow 51820/udp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw enable
# Attention : les ports publiés par Docker contournent ufw. Ouvrez/fermez-les aussi dans le pare-feu de l'hébergeur.

# 2. Créez le dossier et collez le ou les fichiers générés
sudo mkdir -p /etc/docker/containers/wg-easy
cd /etc/docker/containers/wg-easy
sudo nano docker-compose.yml
sudo nano Caddyfile

# 3. Démarrez wg-easy
sudo docker compose up -d
# Suivez les journaux (Ctrl+C pour quitter)
sudo docker compose logs -f wg-easy

# 4. Ouvrez le panneau: https://wg.example.com

Ce fichier a besoin d'un serveur avec une IP publique

Un VPS Cloud Contabo fournit une IPv4 dédiée, des images Linux prêtes pour Docker et un trafic illimité : tout ce dont wg-easy a besoin.

Lien affilié : nous touchons une commission, sans surcoût pour vous.

Carte refusée, ou envie d'un hébergeur américain ? Le VPS Basic d'Ultahost est à 5,52 $/mois sur 24 mois (relevé le 21 octobre 2026) et accepte aussi le Bitcoin, Alipay, WeChat Pay et Qiwi ; vérifie ses conditions pour ton pays. Voir les VPS Ultahost

Voir l'offre VPS Contabo

Des baies de serveurs éclairées en bleu dans un datacenter
Des baies de serveurs éclairées en bleu dans un datacenter

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:14
    container_name: wg-easy
    environment:
      - WG_HOST=vpn.example.com        # domaine ou IP publique de votre VPS
      - PASSWORD_HASH=<hash-bcrypt>     # login interface web
      - WG_DEFAULT_DNS=1.1.1.1
    volumes:
      - ./config:/etc/wireguard         # persistance - gardez-le sur l'hôte
    ports:
      - "51820:51820/udp"               # données WireGuard
      - "51821:51821/tcp"               # interface web (à pare-feuter sur votre IP)
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

Trois lignes font le gros du travail et sont les points de panne habituels :

  • cap_add: NET_ADMIN laisse le conteneur gérer l'interface wg0. Sans elle, le conteneur ne peut pas monter le tunnel.
  • sysctls: net.ipv4.ip_forward=1 transforme la machine en routeur. Sans cela, le tunnel se connecte mais aucun trafic ne le traverse - la cause n°1 du « ça dit connecté mais rien ne marche ».
  • volumes: ./config persiste clés et peers sur l'hôte pour qu'un recreate n'efface pas tous les clients.

Exposez le port UDP de données publiquement ; pare-feutez le port TCP de l'interface web sur votre seule IP - ne laissez jamais 51821 ouvert sur internet.

La checklist hôte (à faire avant d'accuser le conteneur)

Un conteneur peut être parfait et ne rien router à cause de la couche en dessous :

  1. Pare-feu cloud : ouvrez 51820/udp dans le security group de votre fournisseur, pas seulement sur l'hôte. C'est la panne silencieuse n°1 sur un VPS. Voir quel port WireGuard utilise et comment l'ouvrir si vous changez le port par défaut.
  2. Module noyau de l'hôte : la plupart des distros récentes embarquent le module WireGuard (Linux 5.6+). Si modprobe wireguard échoue sur l'hôte, installez les headers du noyau - le conteneur ne peut pas charger un module que l'hôte n'a pas.
  3. DNS des clients : réglez WG_DEFAULT_DNS pour que les clients ne fuitent pas leurs requêtes vers leur ancien résolveur. À combiner avec notre guide anti-fuite DNS WireGuard.

Quand le conteneur est le bon choix - et quand non

Utilisez Docker quand vous faites tourner d'autres services sur la même machine et voulez WireGuard isolé et reproductible, quand vous voulez le tableau de bord wg-easy, ou quand vous redéployez souvent entre hôtes. Tout le setup devient un fichier compose versionnable et déplaçable.

Évitez Docker quand le VPS ne fait que WireGuard. Un apt install wireguard bare-metal plus un fichier de config est plus simple, a une pièce mobile en moins, et se scripte trivialement - voyez nos templates de config WireGuard et le tutoriel complet Contabo + WireGuard. Pour une machine VPN mono-usage, le conteneur ajoute un empaquetage inutile.

Le VPS en dessous

Conteneurisé ou non, WireGuard a besoin d'un hôte avec IP publique et lien correct. Un petit VPS suffit largement - WireGuard est assez léger pour qu'une instance à 4-6 €/mois sature son port réseau bien avant que le CPU ne bronche. Contabo sert ici d'exemple pour son ratio prix/bande passante :

Prenez un VPS Contabo pour votre conteneur WireGuard →

Pour le comparatif prix/performance complet entre fournisseurs, voyez le VPS le moins cher pour un VPN WireGuard.

Pour garder l'essentiel sous la main : la WireGuard Cheat Sheet gratuite (PDF de 5 pages en anglais, téléchargement direct, sans inscription) réunit les tables keepalive et MTU, les commandes wg genkey/wg pubkey/wg genpsk et les quatre vérifications serveur en une ligne à lancer d'abord quand un tunnel ne passe aucun trafic. Le WireGuard Self-Hosting Kit payant (9 USD, en anglais) y ajoute une check-list de dépannage de 12 causes et 11 modèles de configuration.

Un VPN change votre IP. Il ne change pas votre navigateur.

Un tunnel remplace l'adresse que voit un service. Il ne change rien à ce que votre navigateur annonce de lui-même - polices, écran, fuseau, pile graphique - et cette combinaison suffit souvent à vous reconnaître d'une session à l'autre, tunnel ou pas.

Mesurez votre empreinte de navigateur - mesure passive, aucune question, aucun compte, aucune adresse e-mail.

La limite, honnêtement

Docker rend WireGuard portable, pas plus sûr. Le conteneur partage le noyau de l'hôte, tourne avec NET_ADMIN, et n'est verrouillé que dans la mesure où l'hôte l'est. Il ne met pas WireGuard en bac à sable vis-à-vis de la machine - qui a root sur l'hôte possède le tunnel. Traitez le conteneur comme un confort de déploiement, durcissez l'hôte comme si WireGuard y était installé directement, et gardez le port de l'interface web hors d'internet. Faites cela, et le WireGuard conteneurisé est le setup auto-hébergé le plus propre qui soit.

Si vous hésitez encore entre un conteneur, un boîtier chez vous ou un réseau maillé, notre guide créer son propre VPN compare les trois méthodes, leurs coûts et ce que chacune ne protège pas.

★ Datacenter Nuremberg GDPR · ✓ IPv4 dédiée incluse · port 200 Mbit/s

Héberge ton VPN sur ton propre VPS → ContaboAccès root complet · IPv4 publique · choisis ta région→

Questions fréquentes

WireGuard est-il plus lent dans Docker qu'en bare-metal ?
Aucune différence notable. WireGuard tourne dans le noyau Linux de l'hôte, pas dans le conteneur - le conteneur ne contient que l'outillage userspace (wg, wg-quick) et la config. Le chemin des données passe par le même module noyau dans les deux cas, donc débit et latence égalent une install bare-metal. Le conteneur, c'est de l'empaquetage, pas une couche de performance.
Quelle image choisir - linuxserver/wireguard ou wg-easy ?
linuxserver/wireguard est le serveur minimal piloté par fichiers de config : vous gérez les peers en éditant des fichiers ou des variables d'env. wg-easy ajoute une interface web pour créer des peers, afficher des QR codes et voir le trafic en direct - bien plus pratique pour quelques appareils. Prenez linuxserver/wireguard pour l'infra-as-code et beaucoup de peers ; prenez wg-easy pour un tableau de bord et un onboarding client rapide.
Pourquoi mon conteneur WireGuard ne démarre pas ou ne route rien ?
Trois causes habituelles. Un : le conteneur a besoin de la capability NET_ADMIN (et parfois SYS_MODULE) pour gérer l'interface - ajoutez `cap_add: [NET_ADMIN]`. Deux : le forwarding IP doit être activé : `sysctl: net.ipv4.ip_forward=1` dans compose ou sur l'hôte. Trois : le port UDP publié (51820/udp par défaut) doit être ouvert dans le pare-feu cloud ET sur l'hôte. Oubliez-en un et le tunnel se connecte mais ne route rien.
Faut-il encore un VPS pour faire tourner WireGuard dans Docker ?
Seulement si vous voulez un point de sortie public avec une IP stable - pour l'accès distant à un réseau domestique, le conteneur peut tourner sur un serveur maison derrière un port-forward. Pour un VPN auquel vous vous connectez de partout (et pour une IP statique propre), un petit VPS est le choix standard. Une instance à 4-6 €/mois sature son lien en WireGuard sans effort.
Comment persister peers et clés entre les redémarrages du conteneur ?
Montez le dossier de config sur l'hôte (ex. `./config:/config`). Les clés et définitions de peers y vivent, donc `docker compose down && up` garde chaque client fonctionnel. Ne stockez jamais les clés uniquement dans la couche inscriptible du conteneur - un recreate les efface et chaque client doit se ré-enrôler.