Retirer SERVICE_FQDN_PHP_80 et exposer le port explicitement

Le domaine se pose désormais dans l'interface, sur le service `php`.

`SERVICE_FQDN_PHP_80` demandait à Coolify de GÉNÉRER un domaine en …sslip.io.
Utile pour un modèle en un clic, mais en concurrence avec un domaine renseigné
à la main : deux routes pour un même service, dont une seule correspond au DNS
réel. Le proxy répond alors 403 sur le domaine qu'il ne connaît pas — un code
qui n'apparaît nulle part dans l'application, laquelle sert le back-office sur
`/` sans jamais rien refuser.

`expose: ['80']` ajouté. L'image exposait déjà 80, mais aussi 443 et 2019
(l'endpoint d'administration de Caddy) : rien n'obligeait un proxy à deviner
lequel des trois sert l'application.

Vérifié depuis le réseau interne, avec l'en-tête Host public : `/`, `/login` et
`/api/v1/health` répondent 200, et les variables d'environnement arrivent bien
dans le conteneur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Stephan Morand 2026-08-21 12:07:34 +02:00
parent 4766c57dda
commit 5863f3d887
2 changed files with 49 additions and 9 deletions

View file

@ -470,14 +470,39 @@ elle aucun projet ne peut être créé faute de langue source à choisir.
2. Fichier compose : `compose.prod.yaml`. Ne pas laisser `compose.yaml`, que 2. Fichier compose : `compose.prod.yaml`. Ne pas laisser `compose.yaml`, que
Coolify propose par défaut — Docker y fusionnerait `compose.override.yaml`. Coolify propose par défaut — Docker y fusionnerait `compose.override.yaml`.
3. Renseigner les variables du tableau ci-dessus dans l'onglet *Environment*. 3. Renseigner les variables du tableau ci-dessus dans l'onglet *Environment*.
4. Attribuer le domaine au service **`php`**. `SERVICE_FQDN_PHP_80` est déjà 4. Poser le domaine **sur le service `php`**, et sur lui seul. Avec le build
déclaré dans le fichier : Coolify y place le domaine et configure son proxy. pack Docker Compose, Coolify liste chaque service et attend le domaine sur
celui qui répond en HTTP — pas au niveau de la ressource. Un domaine posé
ailleurs laisse `php` sans route, et le proxy répond **403** à un domaine
qu'il ne connaît pas.
5. Déployer, puis lancer la commande d'amorçage ci-dessus depuis le terminal de 5. Déployer, puis lancer la commande d'amorçage ci-dessus depuis le terminal de
la ressource. la ressource.
Le domaine attribué par défaut est en `http://…sslip.io`. Il fonctionne, mais Le fichier ne déclare **pas** `SERVICE_FQDN_PHP_80`. Cette variable magique
les liens d'invitation partiront en clair : posez un vrai domaine en HTTPS avant demande à Coolify de générer un domaine en `…sslip.io` : pratique pour un modèle
d'inviter qui que ce soit. en un clic, mais elle entre en concurrence avec un domaine renseigné à la main,
et l'on se retrouve avec deux routes pour un même service dont une seule
correspond au DNS réel.
### Diagnostiquer un 403
Un 403 sur le domaine vient presque toujours du **proxy**, pas de
l'application : celle-ci ne renvoie jamais 403 sur `/`, elle sert le
back-office. Trois vérifications, dans cet ordre :
```bash
# 1. La pile tourne-t-elle vraiment ? Les quatre services doivent être « running ».
docker ps --filter name=php --filter name=worker --filter name=database
# 2. L'application répond-elle DANS le réseau, proxy contourné ?
docker exec <conteneur-php> curl -sS -o /dev/null -w '%{http_code}\n' http://localhost/api/v1/health
# 3. Le proxy connaît-il le domaine ?
docker exec coolify-proxy cat /traefik/dynamic/*.yaml | grep -i tqslator
```
Si 2 répond `200` et que 3 ne trouve rien, le problème est le routage : le
domaine n'est pas posé sur le service `php`.
Le TLS est terminé par le proxy de Coolify ; Caddy a donc `auto_https off`, et Le TLS est terminé par le proxy de Coolify ; Caddy a donc `auto_https off`, et
`SYMFONY_TRUSTED_PROXIES` est renseigné pour que Symfony lise `SYMFONY_TRUSTED_PROXIES` est renseigné pour que Symfony lise

View file

@ -19,11 +19,26 @@ services:
build: build:
context: . context: .
target: app_prod target: app_prod
# Le port que le proxy doit atteindre. L'image l'expose déjà, mais le
# déclarer ici lève toute ambiguïté : elle expose aussi 443 et 2019
# (l'endpoint d'administration de Caddy), et rien n'oblige un proxy à
# deviner lequel des trois sert l'application.
#
# `expose` et non `ports` : aucune publication sur l'hôte. Le proxy atteint
# le conteneur par le réseau interne, et publier 8080 en plus exposerait
# l'application en clair à côté du HTTPS.
expose:
- '80'
environment: environment:
# Coolify remplace cette variable par le domaine attribué au service et # PAS de `SERVICE_FQDN_PHP_80` ici, et c'est délibéré.
# configure son proxy en conséquence. Sur une VM sans Coolify, retirez #
# cette ligne et ajoutez `ports: ['80:80']`. # Cette variable magique demande à Coolify de GÉNÉRER un domaine (du type
SERVICE_FQDN_PHP_80: '/' # xxxx.sslip.io) et d'y router le service. Elle rend donc service à un
# modèle en un clic, mais elle entre en concurrence avec un domaine
# renseigné à la main : on se retrouve avec deux routes pour un même
# service, dont une seule correspond au DNS réel.
#
# Le domaine se pose donc dans l'interface, sur le service `php`.
SERVER_NAME: ':80' SERVER_NAME: ':80'
APP_ENV: prod APP_ENV: prod