Son projet Symfony dans Coolify
Démarche à suivre dans l'ordre, pour héberger un projet Symfony dans Coolify.
-
Ètapes à suivre par l'étudiant :
- A) Adapter le projet Symfony
- B) Pousser les modifications sur GitHub
- MAJ du projet par l'étudiant
-
Ètapes à suivre par l'enseignant :
- C) Créer la ressources dans Coolify
- D) Déployer
- MAJ du projet par l'enseignant
A) Adapter le projet Symfony
1. compose.yaml
Remplacer le contenu de compose.yaml (à la racine du projet) par :
services:
php:
build: .
restart: unless-stopped
environment:
APP_ENV: prod
APP_SECRET: ${APP_SECRET}
TRUSTED_PROXIES: ${TRUSTED_PROXIES:-REMOTE_ADDR}
DATABASE_URL: mysql://${MARIADB_USER:-app}:${MARIADB_PASSWORD}@database:3306/${MARIADB_DATABASE:-app}?serverVersion=${MARIADB_VERSION:-11.4}.0-MariaDB&charset=utf8mb4
# Caddy écoute en HTTP sur le port 80 : le HTTPS est géré par Traefik (Coolify)
SERVER_NAME: :80
depends_on:
database:
condition: service_healthy
database:
image: mariadb:${MARIADB_VERSION:-11.4}
restart: unless-stopped
environment:
MARIADB_DATABASE: ${MARIADB_DATABASE:-app}
MARIADB_USER: ${MARIADB_USER:-app}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
timeout: 5s
retries: 5
start_period: 60s
volumes:
- database_data:/var/lib/mysql:rw
volumes:
database_data:
Explications :
build: .: l'image du servicephpest construite à partir duDockerfilesitué à la racine du projet (voir l'étape suivante).- Aucun
ports:n'est publié : Coolify (via son proxy Traefik) route le trafic vers le port 80 du servicephp. - Les
${VARIABLE}seront renseignées dans Coolify (partie C).${VARIABLE:-valeur}définit une valeur par défaut.
2. Dockerfile
Créer un fichier Dockerfile à la racine du projet, avec ce contenu :
FROM dunglas/frankenphp:1-php8.4
RUN install-php-extensions intl opcache pdo_mysql zip
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
ENV APP_ENV=prod \
FRANKENPHP_CONFIG="worker ./public/index.php" \
COMPOSER_ALLOW_SUPERUSER=1
WORKDIR /app
COPY . .
RUN composer install --no-dev --optimize-autoloader --no-scripts --no-interaction \
&& composer dump-env prod \
&& php bin/console importmap:install \
&& php bin/console asset-map:compile \
&& php bin/console cache:warmup \
&& mkdir -p var && chown -R www-data:www-data var
# Migrations puis démarrage du serveur
CMD ["sh", "-c", "php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration && frankenphp run --config /etc/caddy/Caddyfile --adapter caddyfile"]
Explications :
- Image de base FrankenPHP avec PHP 8.4 et installation des extensions PHP nécessaires (
pdo_mysqlpour MariaDB). FRANKENPHP_CONFIG="worker ./public/index.php"active le mode worker de FrankenPHP sur le point d'entrée de Symfony.symfony/runtimele détecte automatiquement.- Le build installe les dépendances sans les paquets de dev, prépare la configuration de production, télécharge les bibliothèques JavaScript (
importmap:install), compile les assets et réchauffe le cache. importmap:installest indispensable :composer install --no-scriptsne le lance pas, et le dossierassets/vendor/est dans le.gitignore, donc absent de GitHub. Sans cette commande,asset-map:compileéchoue avecThe "@hotwired/stimulus" vendor asset is missing.- Au démarrage du conteneur, les migrations Doctrine sont exécutées, puis le serveur FrankenPHP est lancé.
--allow-no-migrationest nécessaire tant que le projet n'a aucune migration (dossiersrc/Migrations/vide) : sans lui,doctrine:migrations:migrateéchoue avecThe version "latest" couldn't be reached, there are no registered migrations, et à cause du&&le serveur ne démarre jamais.
3. .dockerignore
Créer un fichier nommé exactement .dockerignore à la racine du projet (à côté du Dockerfile), avec ce contenu :
.git/
.idea/
.vscode/
vendor/
var/
node_modules/
.env.local
.env.*.local
docs/
Explications :
- Ces fichiers ne sont pas copiés dans l'image par le
COPY . .duDockerfile: dépendances locales (réinstallées parcomposer install), cache, historique Git, et surtout secrets locaux. - Ne pas ajouter
.env: il est nécessaire au build (composer dump-env prod).
4. Trusted proxies
Dans config/packages/framework.yaml, ajouter sous framework: :
framework:
trusted_proxies: '%env(TRUSTED_PROXIES)%'
trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix']
Puis ajouter dans le fichier .env (valeur par défaut, committée) :
TRUSTED_PROXIES=
Explications :
- Traefik (le proxy de Coolify) se place devant l'application et transmet les informations de la requête d'origine dans les en-têtes
X-Forwarded-*. Sans cette configuration, Symfony les ignore et génère des URL enhttpau lieu dehttps. %env(TRUSTED_PROXIES)%exige que la variable existe, sinon Symfony s'arrête avecEnvironment variable not found: "TRUSTED_PROXIES". D'où la ligne vide dans.env: en local, il n'y a pas de proxy.- En production,
TRUSTED_PROXIESvautREMOTE_ADDR: lecompose.yaml(étape 1) lui donne cette valeur par défaut, qui l'emporte sur.env.REMOTE_ADDRest un mot-clé de Symfony qui fait confiance à l'adresse IP qui se connecte directement au conteneur, c'est-à-dire Traefik. Cela convient car le conteneur n'est joignable que via le proxy de Coolify (aucunports:publié).
B) Pousser les modifications sur GitHub
git status
git add compose.yaml Dockerfile .dockerignore config/packages/framework.yaml .env
git commit -m "Préparer le déploiement Coolify (FrankenPHP, MariaDB)"
git push origin main
Explications :
- Coolify déploie ce qui est sur GitHub : tous les fichiers créés ou modifiés en A doivent être poussés sur la branche
main. git statuspermet de vérifier la liste des fichiers modifiés avant legit add.- Le dépôt doit être public, car la ressource Coolify est de type Public Repository.
- Ne jamais committer de secrets (
.env.local, mots de passe) : ils se définissent dans Coolify (partie C).
MAJ du projet par l'étudiant
Après chaque modification du projet Symfony, suivre ces étapes dans l'ordre.
5.1 Tester en local
php bin/phpunit
php -S localhost:8000 -t public
Vérifier que les tests passent et que le site fonctionne avant de pousser.
5.2 Si les entités Doctrine ont changé : créer la migration
php bin/console make:migration
php bin/console doctrine:migrations:migrate
- Le fichier de migration généré dans
src/Migrations/doit être committé : il sera exécuté automatiquement au démarrage du conteneur en production (leCMDduDockerfilelancedoctrine:migrations:migrate). - Ne jamais utiliser
doctrine:schema:update: les modifications du schéma passent toujours par une migration. - Les données de la base sont conservées entre les déploiements (volume
database_data).
5.3 Si des dépendances ont changé
composer require vendor/paquet
php bin/console importmap:require nom-du-paquet-js
composer requiremodifiecomposer.jsonetcomposer.lock: les deux fichiers doivent être committés.importmap:requiremodifieimportmap.php: ce fichier doit être committé. Le dossierassets/vendor/n'est pas committé : il est régénéré pendant le build parimportmap:install.
5.4 Pousser les modifications sur GitHub
git status
git add .
git commit -m "Description de la modification"
git push origin main
Vérifier avec git status qu'aucun secret (.env.local) n'est ajouté.
Attendre la fin du git push avant de lancer le déploiement dans Coolify : Coolify déploie le dernier commit présent sur GitHub, pas celui de ton poste. Pour vérifier que le push est bien terminé :
git status
Le message doit indiquer Your branch is up to date with 'origin/main'.
C) Créer la ressources dans Coolify
1. Créer la ressource
-
Projet → choisir l'environnement (ex. 2026-sio2-portfolio) → + New Resource.
-
Choisir Public Repository.
-
Saisir l'URL du dépôt dans l'unique champ Repository URL (https://) :
https://github.com/LaurentBouquet/portfolio-coolify, puis valider (Check repository). -
Sur l'écran suivant, renseigner la configuration de la ressource :
- Branch :
main - Build Pack : Docker Compose
- Base Directory :
/ - Docker Compose Location :
/compose.yaml
- Branch :
-
Cliquer sur Continue : la ressource est créée et ouverte sur sa page Configuration.
2. Variables d'environnement
Dans la ressource, onglet Environment Variables :
-
Coolify détecte les
${VARIABLE}ducompose.yamlet les liste. Si une variable manque, cliquer sur + Add. -
Renseigner la valeur de chaque variable (Key / Value) :
Variable Valeur APP_SECRETvaleur aléatoire (clé secrète de Symfony) MARIADB_PASSWORDvaleur aléatoire (mot de passe de l'utilisateur applicatif) MARIADB_ROOT_PASSWORDvaleur aléatoire (mot de passe root MariaDB) Ces trois valeurs sont des secrets : chacune doit être générée de façon aléatoire et différente des deux autres. Ne jamais copier/coller celles d'un exemple, d'un tutoriel ou d'un autre projet, ni les committer dans Git.
Pour générer une valeur aléatoire (valable sous Windows, Linux et macOS, car PHP est déjà installé pour Symfony) :
php -r "echo bin2hex(random_bytes(32));"Lancer la commande une fois par variable et copier chaque résultat dans la valeur correspondante.
openssl rand -hex 32fait la même chose, maisopenssln'est pas disponible par défaut sous Windows.Aucun besoin de retenir ces valeurs : seule l'application les utilise, et elles restent stockées dans Coolify. Le format hexadécimal évite les caractères spéciaux qui casseraient l'URL
DATABASE_URL.MariaDB ne lit
MARIADB_PASSWORDetMARIADB_ROOT_PASSWORDqu'à la première création de la base (volume vide). Les modifier ensuite dans Coolify ne change pas les mots de passe déjà enregistrés dans la base.TRUSTED_PROXIES(REMOTE_ADDR),MARIADB_USER,MARIADB_DATABASEetMARIADB_VERSIONont une valeur par défaut dans lecompose.yaml: ne les définir que pour la changer.ATTENTION : Saisir la valeur aléatoire à droite du nom de la variable (pas dans le champ
Comment) dans le champ avec un oeil. -
Pour enregistrer chaque variable, cliquer sur le bouton Update situé sur sa ligne. Une variable saisie mais non enregistrée avec Update est perdue.
Les variables ne sont prises en compte qu'au prochain déploiement.
3. Définir le sous-domaine
-
Dans l'onglet General, le champ Domains apparaît pour chaque service du compose. Pour le service
php, saisir par exemple :https://portfolio-demo.app.ndlpavranches.frSi le conteneur n'écoute pas sur le port 80, ajouter le port à la fin :
https://portfolio.app.ndlpavranches.fr:8080. -
Cliquer sur Save. Coolify génère le routage Traefik et le certificat Let's Encrypt.
-
Chez le gestionnaire DNS du domaine, créer un enregistrement de type A pour ce sous-domaine, pointant vers l'adresse IP du serveur Coolify.
D) Déployer
Cliquer sur Deploy (en haut de la ressource), puis suivre les logs du déploiement. Une fois terminé, le site est accessible à l'adresse du sous-domaine.
Dépannage : « dependency failed to start: container database … is unhealthy »
Ouvrir les logs du conteneur database (onglet Logs de la ressource). Si on y lit :
Database is uninitialized and password option is not specified
alors MARIADB_ROOT_PASSWORD (ou MARIADB_PASSWORD) est vide ou absent : MariaDB refuse de démarrer sans mot de passe. Pour corriger :
- Onglet Environment Variables : vérifier que
MARIADB_ROOT_PASSWORD,MARIADB_PASSWORDetAPP_SECRETont chacune une valeur (voir C, étape 2). - Cliquer sur Update sur chaque ligne modifiée.
- Cliquer de nouveau sur Deploy.
Si le conteneur database a déjà démarré une fois avec de mauvais mots de passe, supprimer le volume database_data de la ressource avant de redéployer (MariaDB ne relit les mots de passe qu'à la première initialisation). Attention : cela efface les données de la base.
MAJ du projet par l'enseignant
Après chaque modification du projet Symfony, suivre ces étapes dans l'ordre.
5.5 Redéployer dans Coolify
Dans la ressource Coolify :
-
dans l'onglet General, cliquer sur le bouton Reload Compose file
-
cliquer sur le bouton Deploy (en haut à droite), puis suivre les logs du déploiement.
-
Coolify récupère le dernier commit de la branche
main, reconstruit l'image du servicephpet redémarre les conteneurs. Les migrations sont appliquées au démarrage. -
Le déploiement n'est pas lancé automatiquement par un
git push: il faut cliquer sur Deploy. -
Si seules des variables d'environnement ont changé (onglet Environment Variables, bouton Update), aucun
git pushn'est nécessaire : cliquer directement sur Deploy. -
Au début du log de déploiement, la ligne
Importing LaurentBouquet/portfolio-coolify:main (commit sha …)indique le commit réellement déployé. Il doit correspondre au dernier commit poussé (git log -1 --format=%H). Sinon, le déploiement a été lancé trop tôt : relancer Deploy.
5.6 Vérifier
- Ouvrir le site à l'adresse du sous-domaine et tester la modification.
- En cas d'erreur, consulter les logs du déploiement, puis les logs du conteneur
phpdans Coolify.