Skip to content
selfhostr

guide · 5 min read

Mettre en place Cloudflare Tunnel

Exposer ses services auto-hébergés en HTTPS sans ouvrir un seul port sur sa box, et sans reverse proxy à maintenir. Avec ce que ça coûte vraiment.

Un service auto-hébergé qu'on veut joindre depuis l'extérieur pose toujours la même question : comment le rendre accessible sans ouvrir sa box aux quatre vents ? La réponse habituelle — rediriger les ports 80 et 443 vers un reverse proxy — marche, mais elle vous laisse deux choses sur les bras : un proxy à maintenir, et une IP publique que les scanners trouvent en quelques heures.

Cloudflare Tunnel renverse le sens de la connexion. Un petit démon tourne chez vous et sort vers le réseau Cloudflare ; c'est lui qui maintient le lien. Plus rien n'entre. Aucun port n'est ouvert sur le routeur, et votre IP publique n'apparaît nulle part.

Comptez une quinzaine de minutes, hors propagation DNS.

Ce qu'il faut avoir

  • Un nom de domaine, chez n'importe quel registrar.
  • Un compte Cloudflare. Le plan gratuit suffit pour ce qui suit.
  • Docker sur la machine qui héberge vos services.

Étape 1 — Confier le domaine à Cloudflare

Dans le tableau de bord Cloudflare, Add a domain. Cloudflare vous donne deux serveurs de noms ; allez les saisir chez votre registrar, à la place de ceux qui s'y trouvent.

La propagation prend le temps qu'elle prend — comptez une à deux heures, le temps que le certificat suive. Rien ne sert de relancer : tant que les serveurs de noms n'ont pas basculé, la suite ne fonctionnera pas.

Étape 2 — Créer le tunnel

Zero Trust → Networking → Tunnels → Create a tunnel. Donnez-lui un nom qui désigne la machine et non le service — home-server vieillit mieux que immich, parce qu'un seul tunnel portera bientôt tous vos services.

Cloudflare propose ensuite plusieurs méthodes d'installation : Docker, Kubernetes, paquet système. Choisissez Docker, et gardez le jeton qu'il vous affiche. C'est lui, et lui seul, qui authentifie votre tunnel.

Étape 3 — Lancer le connecteur

La commande fournie par Cloudflare fonctionne telle quelle, mais un docker-compose.yml se relit et se redémarre plus facilement :

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    # --no-autoupdate : c'est l'image qu'on met à jour, pas
    # le binaire dedans. Un conteneur qui se modifie tout
    # seul redémarre au mauvais moment.
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${TUNNEL_TOKEN}

Le jeton va dans un fichier .env à côté, jamais dans le docker-compose.yml lui-même : il donne le droit de publier ce qu'on veut sous votre domaine.

echo "TUNNEL_TOKEN=votre-jeton" > .env
docker compose up -d

Le tunnel se connecte seul. Il passe en Healthy dans le tableau de bord au bout de quelques secondes.

Étape 4 — Exposer un service

Dans votre tunnel, Add a public hostname :

Champ Ce qu'on met
Subdomain immich, git, cloud — ce que vous voulez
Domain votre domaine
Service l'adresse interne du service, vue depuis le conteneur cloudflared

Et c'est en ligne, en HTTPS, sans avoir touché au routeur.

Le piège : quelle adresse mettre dans « Service »

C'est là que la plupart des premières tentatives échouent. L'adresse est celle que voit le conteneur cloudflared, pas celle que voit votre navigateur. Deux cas :

Situation Adresse Exemple
Le service partage un réseau Docker avec cloudflared par nom de conteneur http://opencloud-opencloud-1:9200
Le service est ailleurs sur la machine par IP et port publié http://192.168.0.11:2283

La première forme est préférable : elle ne dépend pas de l'IP de la machine, et elle fonctionne même si le service ne publie aucun port. Pour l'obtenir, joignez cloudflared au réseau du service :

services:
  cloudflared:
    networks:
      - default
      - immich_default

networks:
  immich_default:
    external: true

Toujours http:// et non https:// : le chiffrement s'arrête au réseau Cloudflare, le dernier segment reste sur votre réseau local.

À savoir avant de tout basculer

Le tunnel n'est pas gratuit de conséquences. Trois points valent d'être connus avant d'y faire passer un service, pas après.

Les envois de fichiers sont plafonnés à 100 Mo sur les plans Free et Pro (200 Mo en Business). La limite porte sur le corps de la requête, donc sur ce que vous envoyez — les téléchargements ne sont pas concernés. Pour Immich ou Nextcloud, c'est la première chose qui casse : une vidéo prise au téléphone dépasse souvent ce seuil. Voir la documentation Cloudflare.

Diffuser de la vidéo par le CDN gratuit n'est pas prévu par les conditions d'utilisation. Cloudflare se réserve le droit de limiter l'accès d'un site qui l'utilise « pour servir de la vidéo ou une proportion disproportionnée d'images, de fichiers audio ou d'autres fichiers volumineux » sans les services payants correspondants. Un Jellyfin exposé de cette façon marche — jusqu'au jour où il ne marche plus. Voir les conditions spécifiques.

Le TLS se termine chez Cloudflare. Le certificat est le leur, le déchiffrement se fait chez eux, et le trafic circule en clair dans leur infrastructure avant d'être rechiffré vers vous. C'est le prix du modèle, et il faut le dire : quitter le cloud pour reprendre la main sur ses données, puis faire transiter toutes ses données par un intermédiaire, mérite au moins d'être un choix conscient. Pour ce qui est vraiment sensible, un VPN maillé (Tailscale, WireGuard) ne fait passer le trafic par personne.

Ce que ça remplace, et ce que ça ne remplace pas

Ça remplace le reverse proxy exposé et la redirection de ports — ce guide-là détaille d'ailleurs ce qu'un port ouvert coûte vraiment. Ça ne remplace ni les sauvegardes, ni l'authentification de vos services : un tunnel rend une application joignable, il ne la rend pas sûre. Cloudflare Access, sur le même plan gratuit, ajoute une couche d'authentification devant les services qui n'en ont pas de sérieuse — c'est le complément naturel, et le sujet d'un autre guide.

Video

L3houx met en place un tunnel Cloudflare de bout en bout, sans ouvrir le moindre port — la démonstration de ce que le guide décrit en texte.

Nothing is sent to YouTube until you press play. This site sets no cookies of its own.Watch on YouTube