Auto-héberger le bridge
Le bridge est un petit service dans un conteneur. Il parle à votre console Protect, tient la machine à états de la porte, sert l’app et exécute les règles d’alerte. Il tourne sur un NAS, un Raspberry Pi ou n’importe quelle machine avec Docker, sur amd64 et arm64.
Vous n’êtes pas obligé de l’utiliser. L’app se connecte directement à votre console Protect et fonctionne sur votre réseau domestique sans rien installer d’autre. Le bridge sert si vous voulez des règles d’alerte permanentes, un journal d’activité exportable, les invitations familiales ou des raccourcis fiables en arrière-plan.
Avant de commencer
- Configurez une sortie de relais en Pulse. Dans Protect, ouvrez le relais et configurez en Pulse, type porte de garage, la sortie câblée sur les bornes du bouton-poussoir de votre moteur. Notez de quelle sortie il s’agit : la numérotation commence à 1 dans l’app, mais les identifiants de l’API commencent à 0.
- Montez le capteur et réglez son type de montage sur Garage. C’est ce que lit le bridge pour décider si la porte est ouverte. Avec un autre type de montage, l’appairage automatique ne le retiendra pas.
- Créez une clé d’API Protect. Console → Réglages → Control Plane → Intégrations →
Créer une clé d’API. Copiez-la immédiatement : elle n’est plus affichée ensuite.
Cette clé peut lire toutes les caméras de votre console. Traitez-la comme un mot de passe donnant accès à votre domicile, parce que c’est fonctionnellement ce qu’elle est.
Le lancer
Créez un dossier, déposez-y un docker-compose.yml et un .env, puis démarrez :
# .env : les cinq valeurs qui comptent
GARAGE_BRIDGE_TAG=latest # voir « le tenir à jour » plus bas
PROTECT_URL=https://192.168.1.1 # votre console, avec https://
PROTECT_API_KEY=… # la clé que vous venez de créer
BRIDGE_TOKENS=$(openssl rand -hex 24) # jeton admin : générez-le, ne l'inventez pas
WEBHOOK_SECRET=$(openssl rand -hex 24) # secret de chemin pour le webhook Alarm Manager
TZ=Europe/Zurich docker compose up -d
curl -s localhost:8787/healthz
Vous devriez obtenir {"ok":true,"ready":true,…}, avec la version
réellement en cours d’exécution. Si ready vaut false, le bridge tourne mais
n’a pas encore joint la console, et le message indique pourquoi.
À propos des jetons
BRIDGE_TOKENS est l’identifiant qui ouvre votre porte de garage. Le bridge refuse de
démarrer sur une valeur de moins de 24 caractères, ou sur quoi que ce soit de devinable. Générez-la.
Les téléphones de votre famille n’ont pas besoin d’une entrée ici : ils rejoignent par
invitation, plus bas.
Réseau de l’hôte, ou pas
L’app trouve le bridge via Bonjour, et le multicast ne traverse pas le réseau bridge de Docker : le
compose de référence utilise donc network_mode: host. Si ce n’est pas possible chez vous,
par exemple sur Docker Desktop pour macOS ou Windows, publiez plutôt 8787:8787, mettez
BONJOUR=false et saisissez l’adresse dans l’app. Tout est identique, sauf la découverte.
Appairer votre téléphone
Ne copiez pas votre jeton admin dans l’app. Tant qu’aucun téléphone n’a rejoint, le bridge affiche une invitation à usage unique au démarrage :
docker logs garage-bridge | tail -20
Collez le lien garageopener://join…, ou simplement le code, dans la feuille
Famille → Rejoindre de l’app. Il est valable quinze minutes ; redémarrez le conteneur
pour en obtenir un nouveau. Dès qu’un téléphone a rejoint, l’affichage cesse et les téléphones suivants
sont invités depuis l’app elle-même.
Laisser la console informer le bridge
Le bridge interroge la console régulièrement, mais les webhooks le font réagir immédiatement. Dans Protect, créez deux règles Alarm Manager, capteur ouvert et fermé, publiant toutes deux vers :
http://<hôte-du-bridge>:8787/v1/webhooks/alarm-manager/<WEBHOOK_SECRET> La console doit pouvoir joindre cette adresse ; elle est sur le même réseau que le bridge, donc rien n’est requis depuis Internet. Un secret erroné renvoie un simple 404 : si les règles semblent sans effet, vérifiez d’abord le secret.
Certificats
Votre console présente un certificat auto-signé : la valeur par défaut est donc
PROTECT_TLS=insecure, ce qui convient sur un réseau local. Épinglez-le correctement une
fois en route :
openssl s_client -connect 192.168.1.1:443 -servername 192.168.1.1 </dev/null 2>/dev/null \
| openssl x509 -noout -fingerprint -sha256
Placez le résultat dans PROTECT_TLS=fingerprint:<sha256>. Si votre console possède un
vrai certificat, utilisez system. Le bridge refuse de démarrer avec
insecure si PROTECT_URL n’est pas une adresse locale, car cela exposerait
votre clé d’API à quiconque se trouve sur le chemin.
Y accéder depuis l’extérieur
Définissez PUBLIC_URL sur l’adresse que le téléphone utilisera : c’est elle que portent les
liens d’invitation. Ensuite, choisissez :
| Approche | Remarques |
|---|---|
| VPN vers votre domicile (WireGuard sur l’UDM, ou Tailscale) | Recommandé. Rien n’est exposé ; le téléphone rejoint simplement votre réseau. |
| Tunnel Cloudflare | Vrai nom d’hôte, vrai certificat, aucun port entrant. Mettez TRUST_PROXY=true. |
| Votre propre reverse proxy | Caddy, nginx ou Traefik en terminaison TLS. Mettez TRUST_PROXY=true, et désactivez la mise en tampon sur /v1/events, sinon l’état de la porte accusera du retard. |
| Redirection de port | Non. Cela place sur l’internet public un appareil qui ouvre votre garage, derrière un seul jeton, en général sans TLS. |
TRUST_PROXY compte davantage qu’il n’y paraît. Sans lui, toutes les requêtes semblent
venir du proxy : la limite par adresse sur les invitations devient cinq par minute pour tout votre
foyer. Avec lui, alors que rien en amont ne filtre X-Forwarded-For, un appelant peut
déclarer l’adresse qu’il veut : ne l’activez donc que si un proxy que vous contrôlez est réellement
en place.
Le tenir à jour
latest est la valeur par défaut et convient à la plupart des gens. Docker ne met jamais un
conteneur à jour tout seul : latest signifie simplement que vous obtiendrez la version
courante au prochain pull que vous déciderez de faire. Vous restez donc sur les correctifs de
sécurité sans avoir à suivre les publications.
docker compose pull && docker compose up -d
curl -s localhost:8787/healthz # vérifiez la version récupérée
Épinglez plutôt une version exacte, GARAGE_BRIDGE_TAG=0.4.1, si vous voulez que les mises à
jour soient une décision et non un effet de bord d’un pull, ou si vous utilisez un outil de
mise à jour automatique comme Watchtower. Avec latest et une mise à jour automatique
combinés, une version exigeant un changement de configuration redémarrerait votre bridge sur un refus
de démarrer, sans que vous le voyiez.
Dans tous les cas, lisez le changelog avant un pull. Tout ce qui demande de toucher à la configuration figure sous Action required, et le bridge échoue bruyamment au démarrage plutôt que de tourner dans un état dégradé.
Sources et licence
Le bridge et son contrat OpenAPI sont open source sous licence Apache-2.0. Vous le faites tourner sur votre propre matériel avec un identifiant vers votre console : vous devez pouvoir le lire plutôt que de le croire sur parole, y compris l’audit de sécurité mené avant sa publication.
L’app iOS n’est pas open source, et le service d’alertes cloud non plus. Ce service est quelque chose que nous exploitons, pas que vous faites tourner ; il ne détient aucun identifiant vers votre console et ne peut rien ouvrir ni fermer. Ce qu’il conserve est décrit intégralement sur la page de confidentialité.
Hors périmètre
Une porte par bridge. UniFi Protect uniquement, sans autres relais ni autres hubs. Aucune intégration Home Assistant. Pas d’Android. Une installation sans Docker (Node 22 directement) fonctionnera mais n’est pas prise en charge : Docker est le chemin testé, et le seul que couvrent ces instructions.
Bloqué ? La FAQ couvre les cas courants, et support@garageopener.app vous met en contact avec une personne.
Dernière mise à jour: