« Symfony Docker » : différence entre les versions

 
(13 versions intermédiaires par le même utilisateur non affichées)
Ligne 2 : Ligne 2 :


Pour pouvoir exécuter des commandes '''<code>composer</code>''', '''<code>symfony</code>''' et '''<code>bin/console</code>''' depuis votre machine locale tout en les faisant affecter le conteneur Docker, voici une approche optimale basée sur des '''volumes montés''' et des '''alias pratiques'''.
Pour pouvoir exécuter des commandes '''<code>composer</code>''', '''<code>symfony</code>''' et '''<code>bin/console</code>''' depuis votre machine locale tout en les faisant affecter le conteneur Docker, voici une approche optimale basée sur des '''volumes montés''' et des '''alias pratiques'''.
-----


=== '''1. Montage des volumes pour synchroniser les fichiers''' ===
=== '''1. Montage des volumes pour synchroniser les fichiers''' ===
Ligne 31 : Ligne 28 :
* <code>~/.composer:/tmp/composer</code> : Cache Composer pour éviter de retélécharger les dépendances.
* <code>~/.composer:/tmp/composer</code> : Cache Composer pour éviter de retélécharger les dépendances.
* <code>working_dir</code> : S’assure que les commandes s’exécutent dans <code>/var/www/html</code>.
* <code>working_dir</code> : S’assure que les commandes s’exécutent dans <code>/var/www/html</code>.
-----


=== '''2. Exécuter des commandes dans le conteneur depuis l’hôte''' ===
=== '''2. Exécuter des commandes dans le conteneur depuis l’hôte''' ===
Ligne 63 : Ligne 57 :
dc-console make:migration
dc-console make:migration
dc-symfony serve -d</syntaxhighlight>
dc-symfony serve -d</syntaxhighlight>
-----


=== '''3. Cas particulier : Développement d’un bundle local''' ===
=== '''3. Cas particulier : Développement d’un bundle local''' ===


Si vous développez un bundle en local et qu’il est lié via <code>composer.json</code> en <code>&quot;type&quot;: &quot;path&quot;</code>, assurez-vous que : 1. '''Le chemin est correct''' dans <code>composer.json</code> : <code>json    {       &quot;require&quot;: {           &quot;mon/bundle-local&quot;: &quot;*&quot;,           &quot;symfony/framework-bundle&quot;: &quot;^6.0&quot;        },        &quot;repositories&quot;: [           {               &quot;type&quot;: &quot;path&quot;,               &quot;url&quot;: &quot;./packages/mon-bundle-local&quot;            }       ]   }</code> 2. '''Le volume est bien monté''' dans <code>docker-compose.yml</code> : <code>yaml    volumes:      - ./:/var/www/html      - ./packages/mon-bundle-local:/var/www/html/packages/mon-bundle-local  # Si le bundle est dans un sous-dossier</code> 3. '''Reconstruire l’autoload''' après modification du bundle : <code>bash    docker-compose exec app composer dump-autoload</code>
Si vous développez un bundle en local et qu’il est lié via <code>composer.json</code> en <code>"type": "path"</code>, assurez-vous que :<br />
1. '''Le chemin est correct''' dans <code>composer.json</code> :  
<syntaxhighlight lang="json">{      
    "require": {  
        "mon/bundle-local": "*",  
        "symfony/framework-bundle": "^6.0"
    },         
    "repositories": [
        {
            "type": "path",
            "url": "./packages/mon-bundle-local"
        }
    ]
}
</syntaxhighlight>


2. '''Le volume est bien monté''' dans <code>docker-compose.yml</code> :
<syntaxhighlight lang="yaml"> 
volumes:
- ./:/var/www/html
- ./packages/mon-bundle-local:/var/www/html/packages/mon-bundle-local
# Si le bundle est dans un sous-dossier
</syntaxhighlight>


-----
3. '''Reconstruire l’autoload''' après modification du bundle :
<syntaxhighlight lang="bash" copy>bash docker-compose exec app composer dump-autoload</syntaxhighlight>


=== '''4. Optimisation pour le dev : Xdebug + volumes''' ===
=== '''4. Optimisation pour le dev : Xdebug + volumes''' ===
Ligne 85 : Ligne 99 :
       - ./:/var/www/html
       - ./:/var/www/html
       - ~/.composer:/tmp/composer</syntaxhighlight>
       - ~/.composer:/tmp/composer</syntaxhighlight>
-----


=== '''Récapitulatif des bonnes pratiques''' ===
=== '''Récapitulatif des bonnes pratiques''' ===
Ligne 110 : Ligne 122 :
| Alias shell + volumes montés + Xdebug
| Alias shell + volumes montés + Xdebug
|}
|}
-----


==== '''Conclusion''' ====
==== '''Conclusion''' ====
Ligne 125 : Ligne 134 :


La commande '''<code>composer dump-autoload</code>''' est une commande essentielle dans l’écosystème PHP/Composer. Elle régénère le fichier d’'''autoloading''' (chargement automatique des classes) sans réinstaller les dépendances. Voici ce qu’elle fait en détail :
La commande '''<code>composer dump-autoload</code>''' est une commande essentielle dans l’écosystème PHP/Composer. Elle régénère le fichier d’'''autoloading''' (chargement automatique des classes) sans réinstaller les dépendances. Voici ce qu’elle fait en détail :
-----


=== '''À quoi sert <code>composer dump-autoload</code> ?''' ===
=== '''À quoi sert <code>composer dump-autoload</code> ?''' ===
Ligne 150 : Ligne 156 :
<li><p>La commande les intègre dans l’autoloader.</p></li></ul>
<li><p>La commande les intègre dans l’autoloader.</p></li></ul>
</li></ol>
</li></ol>
-----


=== '''Quand l’utiliser ?''' ===
=== '''Quand l’utiliser ?''' ===
Ligne 173 : Ligne 176 :
| <code>composer dump-autoload</code>
| <code>composer dump-autoload</code>
|}
|}
-----


=== '''Différence avec <code>composer install</code> et <code>composer update</code>''' ===
=== '''Différence avec <code>composer install</code> et <code>composer update</code>''' ===
Ligne 187 : Ligne 187 :
* '''<code>composer dump-autoload</code>''' :<br />
* '''<code>composer dump-autoload</code>''' :<br />
'''Ne touche pas aux dépendances''' – ne fait que mettre à jour l’autoloader.
'''Ne touche pas aux dépendances''' – ne fait que mettre à jour l’autoloader.
-----


=== '''Exemple concret dans un projet Symfony''' ===
=== '''Exemple concret dans un projet Symfony''' ===
Ligne 206 : Ligne 203 :
<syntaxhighlight lang="bash">composer dump-autoload</syntaxhighlight></li></ul>
<syntaxhighlight lang="bash">composer dump-autoload</syntaxhighlight></li></ul>
</li></ol>
</li></ol>
-----


=== '''Bonnes pratiques''' ===
=== '''Bonnes pratiques''' ===
Ligne 222 : Ligne 216 :
Si vous montez un volume (<code>./:/var/www/html</code>), exécutez la commande '''dans le conteneur''' :</p>
Si vous montez un volume (<code>./:/var/www/html</code>), exécutez la commande '''dans le conteneur''' :</p>
<syntaxhighlight lang="bash">docker-compose exec app composer dump-autoload</syntaxhighlight></li></ul>
<syntaxhighlight lang="bash">docker-compose exec app composer dump-autoload</syntaxhighlight></li></ul>
-----


=== '''Résumé''' ===
=== '''Résumé''' ===
Ligne 239 : Ligne 230 :


== '''Symfony cache et composer cache avec Docker''' : ==
== '''Symfony cache et composer cache avec Docker''' : ==
-----


=== '''1. Rôle du dossier <code>/var/cache</code> dans Symfony''' ===
=== '''1. Rôle du dossier <code>/var/cache</code> dans Symfony''' ===
Ligne 249 : Ligne 237 :
'''Problème avec Docker :'''<br />
'''Problème avec Docker :'''<br />
Par défaut, ce cache est régénéré à chaque démarrage du conteneur → '''ralentissements''' (surtout en dev).
Par défaut, ce cache est régénéré à chaque démarrage du conteneur → '''ralentissements''' (surtout en dev).
-----


=== '''2. Stratégies pour optimiser le cache avec Docker''' ===
=== '''2. Stratégies pour optimiser le cache avec Docker''' ===
Ligne 265 : Ligne 250 :


'''Inconvénients :''' - Peut causer des problèmes de permissions (solved avec <code>chmod</code> ou <code>entrypoint.sh</code>).
'''Inconvénients :''' - Peut causer des problèmes de permissions (solved avec <code>chmod</code> ou <code>entrypoint.sh</code>).
-----


==== '''B. Utiliser un volume Docker nommé (prod + dev)''' ====
==== '''B. Utiliser un volume Docker nommé (prod + dev)''' ====
Ligne 287 : Ligne 269 :


exec "$@"</syntaxhighlight>
exec "$@"</syntaxhighlight>
-----


==== '''C. Cache warming en production''' ====
==== '''C. Cache warming en production''' ====
Ligne 302 : Ligne 282 :
COPY --from=builder /app /var/www/html
COPY --from=builder /app /var/www/html
RUN php bin/console cache:warmup  # ⚡ Pré-chauffe le cache</syntaxhighlight>
RUN php bin/console cache:warmup  # ⚡ Pré-chauffe le cache</syntaxhighlight>
-----


=== '''3. Gestion des environnements''' ===
=== '''3. Gestion des environnements''' ===
Ligne 321 : Ligne 299 :
| Cache éphémère (pas de montage)
| Cache éphémère (pas de montage)
|}
|}
-----


=== '''4. Exemple complet (docker-compose.yml)''' ===
=== '''4. Exemple complet (docker-compose.yml)''' ===
Ligne 343 : Ligne 318 :
       APP_ENV: dev
       APP_ENV: dev
       COMPOSER_CACHE_DIR: /tmp/composer</syntaxhighlight>
       COMPOSER_CACHE_DIR: /tmp/composer</syntaxhighlight>
-----
=== '''5. Bonnes pratiques''' ===
=== '''5. Bonnes pratiques''' ===


Ligne 353 : Ligne 325 :
<li><p>'''Permissions''' : Résolvez-les via <code>entrypoint.sh</code> ou <code>docker-compose</code> :</p>
<li><p>'''Permissions''' : Résolvez-les via <code>entrypoint.sh</code> ou <code>docker-compose</code> :</p>
<syntaxhighlight lang="yaml">user: "${UID:-1000}:${GID:-1000}"</syntaxhighlight></li></ol>
<syntaxhighlight lang="yaml">user: "${UID:-1000}:${GID:-1000}"</syntaxhighlight></li></ol>
-----


=== '''Différence avec Composer Cache''' ===
=== '''Différence avec Composer Cache''' ===
Ligne 377 : Ligne 346 :
| Warming dans l’image + volume
| Warming dans l’image + volume
|}
|}
-----


=== '''Résumé''' ===
=== '''Résumé''' ===
Ligne 503 : Ligne 469 :


=== 3 bis. docker-compose.yml (option dans compose.yml) ===
=== 3 bis. docker-compose.yml (option dans compose.yml) ===
Voir [[#composer-optionnel|Composer optionnel]].
<syntaxhighlight lang="yaml">
<syntaxhighlight lang="yaml">
   # Optionnel: Composer en tant que service
   # Optionnel: Composer en tant que service
Ligne 597 : Ligne 564 :
</li></ul>
</li></ul>
</li></ol>
</li></ol>


=== 8. Avantages de cette configuration ===
=== 8. Avantages de cette configuration ===
Ligne 650 : Ligne 616 :
exec docker-php-entrypoint "$@"</syntaxhighlight>
exec docker-php-entrypoint "$@"</syntaxhighlight>
Cela signifie : 1. Votre script fait d’abord son travail personnalisé (vérifier/vendor et installer les dépendances si besoin) 2. Ensuite, il “passe la main” au processus PHP-FPM officiel, devenant ainsi le processus principal du container
Cela signifie : 1. Votre script fait d’abord son travail personnalisé (vérifier/vendor et installer les dépendances si besoin) 2. Ensuite, il “passe la main” au processus PHP-FPM officiel, devenant ainsi le processus principal du container


=== Alternative sans <code>exec</code> ===
=== Alternative sans <code>exec</code> ===
Ligne 670 : Ligne 635 :
----
----


<span id="composer-optionnel"></span>
=== '''composer:latest (optionnel)''' ===
=== '''composer:latest (optionnel)''' ===


Ligne 724 : Ligne 690 :
* Mais dans votre cas, avec des bundles locaux et une configuration spécifique, avoir un service dédié est plus fiable.
* Mais dans votre cas, avec des bundles locaux et une configuration spécifique, avoir un service dédié est plus fiable.


=== En résumé : ===
==== En résumé : ====


{| class="wikitable"
{| class="wikitable"
Ligne 747 : Ligne 713 :
Le choix dépend de votre workflow, d’où le caractère optionnel !
Le choix dépend de votre workflow, d’où le caractère optionnel !


== '''version complète optimisée avec un service Composer dédié''' ==
Voici une version complète optimisée avec '''un service Composer dédié''', tout en gardant la configuration pour vos bundles locaux et l’intégration avec PHPStorm.
=== Structure finale recommandée ===
<pre>~/debian/projet/
├── app/                  # Projet Symfony principal
│  ├── src/
│  ├── vendor/
│  ├── public/
│  └── composer.json
├── Bundles/              # Bundles locaux
│  ├── bundlea/          # Bundle A
│  └── bundleb/          # Bundle B
├── docker/
│  ├── apache/
│  │  └── vhost.conf    # Config Apache
│  ├── php/
│  │  └── php.ini      # Config PHP
│  └── entrypoint.sh    # Script d'initialisation
├── .env                  # Variables d'environnement
├── Dockerfile            # Build PHP-FPM
└── docker-compose.yml    # Configuration Docker</pre>
=== 1. Fichier <code>.env</code> (nouveau) ===
<syntaxhighlight lang="ini"># PostgreSQL
POSTGRES_USER=symfony
POSTGRES_PASSWORD=ChangeMe
POSTGRES_DB=app
# Symfony
APP_ENV=dev
DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?serverVersion=15&charset=utf8"</syntaxhighlight>
=== 2. Dockerfile (optimisé) ===
<syntaxhighlight lang="dockerfile">FROM php:8.2-fpm
# Dependencies + Extensions PHP
RUN apt-get update && apt-get install -y \
    git \
    libpq-dev \
    libzip-dev \
    libevent-dev \
    && docker-php-ext-install pdo pdo_pgsql zip \
    && pecl install event \
    && docker-php-ext-enable event
# Script d'entrée
COPY docker/entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
WORKDIR /var/www
ENTRYPOINT ["entrypoint.sh"]</syntaxhighlight>
=== 3. docker-compose.yml (complet) ===
<syntaxhighlight lang="yaml">version: '3.8'
services:
  php:
    build: .
    volumes:
      - ./app:/var/www
      - ./Bundles:/var/www/bundles
    env_file:
      - .env
    depends_on:
      - postgres
  apache:
    image: httpd:2.4
    ports:
      - "8080:80"
    volumes:
      - ./app/public:/var/www/html
      - ./docker/apache/vhost.conf:/usr/local/apache2/conf/extra/httpd-vhosts.conf
    depends_on:
      - php
  postgres:
    image: postgres:15
    env_file:
      - .env
    volumes:
      - postgres_data:/var/lib/postgresql/data
  composer:
    image: composer:2
    volumes:
      - ./app:/var/www
      - ./Bundles:/var/www/bundles
      - composer_cache:/tmp
    working_dir: /var/www
    environment:
      - COMPOSER_CACHE_DIR=/tmp
    entrypoint: ["composer"]
volumes:
  postgres_data:
  composer_cache:</syntaxhighlight>
=== 4. docker/apache/vhost.conf ===
<syntaxhighlight lang="apache"><VirtualHost *:80>
    DocumentRoot /var/www/html
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/public/$1
   
    <Directory "/var/www/html">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost></syntaxhighlight>
=== 5. docker/entrypoint.sh (optimisé) ===
<syntaxhighlight lang="bash">#!/bin/bash
set -e
# Attendre que PostgreSQL soit prêt
while ! nc -z postgres 5432; do
  sleep 1
done
# Lancer PHP-FPM
exec php-fpm</syntaxhighlight>
=== 6. Configuration Composer (app/composer.json) ===
<syntaxhighlight lang="json">{
  "repositories": [
    {
      "type": "path",
      "url": "../Bundles/bundlea",
      "options": {
        "symlink": true
      }
    },
    {
      "type": "path",
      "url": "../Bundles/bundleb",
      "options": {
        "symlink": true
      }
    }
  ]
}</syntaxhighlight>
=== 🔧 Workflow recommandé ===
<ol style="list-style-type: decimal;">
<li><p>'''Initialisation''' :</p>
<syntaxhighlight lang="bash">docker-compose build
docker-compose up -d</syntaxhighlight></li>
<li><p>'''Installer les dépendances''' (via le service Composer) :</p>
<syntaxhighlight lang="bash">docker-compose run --rm composer install</syntaxhighlight></li>
<li><p>'''Mettre à jour un bundle local''' :</p>
<syntaxhighlight lang="bash">docker-compose run --rm composer update vendor/bundlea</syntaxhighlight></li>
<li><p>'''Accéder aux logs''' :</p>
<syntaxhighlight lang="bash">docker-compose logs -f php</syntaxhighlight></li>
<li><p>'''Arrêter l’environnement''' :</p>
<syntaxhighlight lang="bash">docker-compose down</syntaxhighlight></li></ol>
=== 🛠 Intégration PHPStorm ===
# '''Configurer les mappings''' :
#* <code>/var/www</code> → <code>./app</code>
#* <code>/var/www/bundles</code> → <code>./Bundles</code>
# '''Interpréteur PHP''' :
#* Utiliser le PHP du container (Settings &gt; PHP)
# '''Server Configuration''' :
#* Nom : Docker Apache
#* Host : localhost
#* Port : 8080
#* Path mappings comme ci-dessus
=== ✅ Points clés de cette configuration ===
* '''Service Composer isolé''' avec cache persistant (<code>composer_cache</code>)
* '''Symlinks des bundles locaux''' fonctionnels grâce au volume partagé
* '''Environnement reproductible''' avec PostgreSQL intégré
* '''Optimisé pour PHPStorm''' avec les bons mappings de chemins
* '''Entrypoint minimaliste''' qui attend juste que la DB soit prête
Cette solution offre un équilibre parfait entre isolation des services et facilité de développement avec les bundles locaux.




[[Catégorie:Symfony]] [[Catégorie:Docker]]
[[Catégorie:Symfony]] [[Catégorie:Docker]]