Le scénario : on veut ajouter dans Coolify (qui tourne sur srv-a) une application qui clone son code depuis le Gitea srv-a lui-même, accessible uniquement via le mesh WireGuard (10.8.0.1:3000 HTTP, 10.8.0.1:222 SSH). Tout est local, le container Coolify atteint 10.8.0.1:3000 sans souci (HTTP 200). Et pourtant Coolify refuse l’ajout. Deux validations différentes, deux contournements distincts.
Piège 1 — « The api url must not point to a private or reserved IP address » (création source Gitea/GitHub App)
Coolify v4 a une règle Laravel App\Rules\SafeExternalUrl (cf. app/Rules/SafeExternalUrl.php) qui :
- parse l’URL
- résout le hostname via
gethostbyname() - rejette si l’IP est privée ou réservée (
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) - rejette aussi les hostnames se terminant par
.local,.internal,localhost,0.0.0.0,::1
Cette règle est appliquée à la création de sources Git (GitHub App), webhooks, S3 storage, notifications. Donc impossible de mettre http://10.8.0.1:3000 comme API URL d’un « Source Gitea » — la validation est cassée même si un hostname custom résout vers 10.8.0.1, car le gethostbyname() final voit l’IP privée.
Contournement : ne pas créer de « source Gitea » du tout. Coolify v4 supporte le pattern Private Repository (Deploy Key) : créer une SSH key dans Coolify, l’ajouter comme Deploy Key dans Gitea, et donner directement l’URL SSH du repo dans l’app. La règle SafeExternalUrl ne s’applique PAS aux URLs de repos d’applications.
Piège 2 — « The Repository cannot use IP addresses » (URL de repo)
Coolify a une seconde validation, plus simple : l’URL de repo ne doit pas contenir d’IP nue. Une URL Git SSH classique style SCP-like git@10.8.0.1:222/perso/repo.git est rejetée.
Contournement : utiliser le schéma ssh:// explicite, qui rend l’URL « URL-like » plutôt que SCP-like. La validation laisse passer :
ssh://git@10.8.0.1:222/perso/projet-a.git
Avec le schéma, :222 est interprété correctement comme port SSH (et pas comme path 222/perso/… ce qu’aurait fait la version SCP-like). Git accepte aussi parfaitement cette forme.
Mémo
- Source Gitea/GitHub App via UI = bloquée par
SafeExternalUrlsi IP privée. - Application « Private Repo (Deploy Key) » = pas bloquée par
SafeExternalUrl, juste par la règle « no IP nue ». - Pour exposer Gitea derrière WG à Coolify, utiliser la forme
ssh://git@<ip-privée>:<port>/<owner>/<repo>.git.
Le bonus de la 2e voie : on génère une SSH key par projet/dépôt Coolify, on l’ajoute comme Deploy Key spécifique à un repo dans Gitea (lecture seule par défaut). Surface d’attaque plus petite qu’un PAT global.