Configurer un environnement symfony avec Docker [Résolu]

Signaler
-
Messages postés
10
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
10 avril 2021
-
Bonjour, J'essaye de configurer un environnement de développement symfony avec Docker. J'ai actuellement trois conteneurs : mySql, PhpMyAdmin (port 8080), Apache et Php (port 8741). Problème, lorsque je lance mon site, j'ai l'erreur : unable to connect.

Voici mes fichier

docker-compose.yaml :



version: "3.3"
services:

db:
image: mysql
container_name: db_docker_symfony
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
networks:
- dev

phpmyadmin:
image: phpmyadmin
container_name: phpmyadmin_docker_symfony
restart: always
depends_on:
- db
ports:
- 8080:80
environment:
PMA_HOST: db
networks:
- dev

www:
build: php
container_name: www_docker_symfony
ports:
- "8741:80"
volumes:
- ./php/vhosts:/etc/apache2/sites-enabled
- ./:/var/www
restart: always
networks:
- dev

networks:
dev:

volumes:
db-data:



Dockerfile :


FROM php:7.4-apache

RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf \
\
&& apt-get update \
&& apt-get install -y --no-install-recommends \
locales apt-utils git libicu-dev g++ libpng-dev libxml2-dev libzip-dev libonig-dev libxslt-dev unzip \
\
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen \
&& echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen \
&& locale-gen \
\
&& curl -sS https://getcomposer.org/installer | php -- \
&& mv composer.phar /usr/local/bin/composer \
\
&& curl -sS https://get.symfony.com/cli/installer | bash \
&& mv /root/.symfony/bin/symfony /usr/local/bin \
\
&& docker-php-ext-configure \
intl \
&& docker-php-ext-install \
pdo pdo_mysql opcache intl zip calendar dom mbstring gd xsl \
\
&& pecl install apcu && docker-php-ext-enable apcu

WORKDIR /var/www/



vhosts.conf


<VirtualHost *:80>
ServerName localhost

DocumentRoot /var/www/project/public
DirectoryIndex /index.php

<Directory /var/www/project/public>
AllowOverride None
Order Allow,Deny
Allow from All

FallbackResource /index.php
</Directory>

# uncomment the following lines if you install assets as symlinks
# or run into problems when compiling LESS/Sass/CoffeeScript assets
# <Directory /var/www/project>
# Options FollowSymlinks
# </Directory>
# optionally disable the fallback resource for the asset directories
# which will allow Apache to return a 404 error when files are
# not found instead of passing the request to Symfony

<Directory /var/www/project/public/bundles>
FallbackResource disabled
</Directory>

ErrorLog /var/log/apache2/project_error.log
CustomLog /var/log/apache2/project_access.log combined

# optionally set the value of the environment variables used in the application
#SetEnv APP_ENV prod
#SetEnv APP_SECRET <app-secret-id>
#SetEnv DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name"
</VirtualHost>


Tree :


symfony
docker-compose.yaml
php
- Dockerfile
- vhosts
- vhosts.conf

19 réponses

Messages postés
29703
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
8 avril 2021
7 066
Bonjour,

Avant tout je n'ai jamais utilisé docker, mais il y a quelques points qui me paraissent étranges.
  • Comment se fait-il que le port du serveur mysql n'est pas spécifié (est-ce que par défaut le serveur mysql pourra bien écouter sur le port 3306) ?
  • Tu as mis un login mot de passe en clair dans ton fichier vhosts.conf or généralement les couples login mot de passe sont stockés dans des fichiers spécifiques avec des droits restreints (ce qui n'est pas le cas de ce fichier). Est-ce normal ?
  • Pourquoi as-tu besoin de préciser un port pour symfony/php : c'est un framework, servi par ton serveur apache, mais pas un serveur. Du coup seul apache écoute effectivement sur un port (par défaut 80).
  • Lancer la commande
    echo "ServerName localhost" >> /etc/apache2/apache2.conf
    va ajouter la directive en fin de fichier, or ceci devrait être insérer dans le bon bloc de configuration (et de toute façon, il me semble que ça fait partie de la configuration par défaut).
  • Enfin quelle est la finalité de ce qui semble être des redirections (8080:80 etc...) ?


En tout cas voici ce que je peux te dire : pour une installation LAMP (Linux Apache MySQL PHP) classique on installe les paquets ainsi :

apt update
apt install apache2 default-mysql-server libapache2-mod-php
a2enmod php7.3
systemctl apache2 restart


Le serveur mysql écoute traditionnellement sur le port 3306 et le serveur web (ici apache2) sur le port 80. PHP est supporté par le serveur web en installant le module apache approprié.

phpmyadmin
s'installe directement via :

apt install phpmyadmin


Cela créera automatiquement un vhost apache accessible dans ton navigateur via l'URL 1.2.3.4/phpmyadmin si 1.2.3.4 est l'IP de ton serveur web.

Pour installer symfony (que je n'ai jamais installé) tu peux installer le paquet
composer
qui t'évitera d'avoir à le télécharger manuellement

apt install composer


Bonne chance
Bonjour, merci pour ta réponse, je débute donc je ne saurais pas répondre à toutes ces questions mais j'ai essayé une autre configuration et ça semble fonctionner. Pourrais-tu me dire ce que tu en pense ?

Tree :


├── infra
│   ├── docker-compose.yaml
│   ├── logs
│   │   └── nginx
│   │   ├── access.log
│   │   └── error.log
│   ├── nginx
│   │   ├── Dockerfile
│   │   └── nginx.conf
│   └── php
│   └── Dockerfile
└── symfony



/infra/nginx/Dockerfile

FROM nginx:alpine
WORKDIR /var/www
CMD ["nginx"]
EXPOSE 80


/infra/nginx/nginx.conf


user nginx;
worker_processes 4;
daemon off;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;

server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;

server_name localhost;
root /var/www/public;
index index.php index.html index.htm;

location / {
try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 600;
include fastcgi_params;
}

location ~ /\.ht {
deny all;
}
}
}


/infra/php/Dockerfile


FROM php:8.0.0RC3-fpm-alpine
RUN apk --update --no-cache add git
RUN docker-php-ext-install pdo_mysql
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR /var/www
CMD composer install ; php-fpm
EXPOSE 9000


/infra/docker-compose-yaml


version: '3'

services:
php:
container_name: "php-fpm"
build:
context: ./php
environment:
- APP_ENV=${APP_ENV}
- APP_SECRET=${APP_SECRET}
volumes:
- ${APP_FOLDER}:/var/www

nginx:
container_name: "nginx"
build:
context: ./nginx
volumes:
- ${APP_FOLDER}:/var/www
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./logs:/var/log
depends_on:
- php
ports:
- "80:80"

db:
image: mysql
container_name: database_docker_symfony
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
networks:
- dev

phpmyadmin:
image: phpmyadmin
container_name: php_my_admin_docker_symfony
restart: always
depends_on:
- db
ports:
- 8080:80
environment:
PMA_HOST: db
networks:
- dev
networks:
dev:
volumes:
db-data:



/infra/.env


APP_FOLDER=../symfony
APP_ENV=dev
APP_SECRET=
Messages postés
29703
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
8 avril 2021
7 066
Bonjour

Le fait que ça marche montre que déjà ça tient plus la route. Je n'ai rien vu de choquant à part peut-être le
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
qui à mon avis n'est pas souhaitable car peut encourager à laisser des accès sans mots de passe à la base de données.

Autre point un peu surprenant, le port 80 est explicitement ouvert mais ton dockerfile semble spécifier que phpmyadmin correspond au port 8080 qui n'est pas exposé. Je ne sais pas si c'est normal. Sous debian en tout cas, tu peux tout a fait avoir un phpmyadmin qui comme le site correspond au port 80 et c'est le serveur web (
apache2
dans ton premier message,
nginx
dans le second) qui en fonction de l'URL déterminera si la personne accède à phpmyadmin ou un autre site. Bref, j'ai un peu de mal à voir l'intérêt de la directive
8080:80
dans le cas présent.

Note enfin que dans ton second message, tu utilses php-fpm qui permet d'accélérer l'exécution du code PHP (voir notamment cet article). Ça semble être un bon ajout.

Bonne chance
Bonjour et merci pour ta réponse. Effectivement , ça semble fonctionner, seul problème, lorsque j'essaye de créer un controller en ligne de commande dans mon projet, j'ai cette erreur : Your Composer dependencies require a PHP version ">= 8.0.0". You are running 7.4.3.

As-tu une idée de comment la résoudre ? Merci ;)
Messages postés
29703
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
8 avril 2021
7 066
Bonjour,

Ton
/infra/php/Dockerfile
semble vouloir récupérer la "bonne" version de php. Sur les debian actuelles, la dernière version de php disponible via
apt
est
php7.4
, donc je suppose que c'est ton cas également. En bref, je suspecte que docker a pris ce qu'il a pu, mais il n'y a juste pas de php8 de disponible. On peut donc se demander si un
php7.4
n'est pas suffisant dans ton cas.
  • Dans une installation non docker, on aurait lancé sous debian :
    apt install php php-fpm
    qui en cascade aurait installé les paquets
    php7.4
    et
    php7.4-fpm
    .
  • Dans une installation docker, il semblerait que
    FROM php:8.0.0RC3-fpm-alpine
    soit supposé installer php8, mais manifestement, ça n'a pas marché.


Pour revenir à l'erreur
Your Composer dependencies require a PHP version ">= 8.0.0". You are running 7.4.3.
, on peut tenter de bidouiller ton
composer.json
pour relâcher cette contrainte, comme expliqué ici. L'espoir étant qu'un php7.4 suffise dans ton cas...

Bonne chance
Bonjour, J'ai finalement repris cette même configuration en la plaçant dans un dossier à la racine de mon projet symfony. Mais lorsque je me rend sur mon site en localhost, j'ai une erreur 404. Une idée du problème ?
Messages postés
29703
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
8 avril 2021
7 066
Bonjour,

C'est un peu vague, il faut que tu regardes dans les logs de ton serveur web les erreurs pour voir à quel(s) fichier(s) le serveur web a voulu accéder lorsque tu as tenté d'accéder à la page. Pour cela le mieux est de regarder ce qui s'est passé dans les logs de ton serveur web (voir cette discussion).

Bonne chance
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Bonjour,

Peux-tu fournir à nouveau l'ensemble des fichiers et la structure afin de nous permettre de vérifier ? L'idéal serait un Github (sans le code source de ton application).

La seule chose anormale détectée par mon radar lors de mon survol rapide est le
CMD composer install ;  php-fpm
dans le fichier /infra/php/Dockerfile.

Je ne comprends pas pourquoi tu exécutes un
composer install
à chaque démarrage du container (via le CMD). Le but de l'image "php-fpm" est d'offrir un environnement qui contient les outils nécessaires pour le développeur, dont composer, mais le "composer install" (et toute autre commande permettant d'exécuter un outil de développement) devrait être exécutée par le développeur lorsque cela est nécessaire. En l'état, l'ajout d'une dépendance dans le composer.json nécessiterait ou bien de redémarrer le container pour exécuter le "composer install", ou bien d'exécuter la commande manuellement depuis le container. C'est la seconde option qui convient le mieux, puisque le but de ce container est de mettre ces outils à la disposition du développeur, sans nécessairement les exécuter au démarrage. On ne choisit pas la première option parce que il n'y a pas de raison d'exécuter "composer install" lorsque ça n'est pas nécessaire, si par exemple il n'y a eu aucun changement depuis la dernière exécution.

Les outils de développement ou de build (npm, webpack, ...) peuvent être exécutés lors de la construction de l'image si le but de l'image est de contenir l'application (donc on fera un COPY pour intégrer les sources dans l'images Docker, plutôt que de les "bind" sous la forme de volume), et de la construire à partir de ses sources afin qu'elle soit prête à être exécutée dans le container. En fait, pour construire l'image finale qui sera ensuite déployée, dans le but de générer une image Docker aussi légère que possible, on va extraire le résultat finale et l'intégrer dans une nouvelle image qui ne contiendra plus les outils de dév/build mais uniquement l'application prête à l'emploi, grâce aux Dockerfile dits "multistage"¹.

Si j'ai bien compris ton objectif, c'est de mettre en place l'environnement de développement "à la Docker", et non « d'empaqueter » l'application construite dans une image Docker.

¹ Voir ici : https://docs.docker.com/develop/develop-images/multistage-build/
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Tout fonctionne correctement chez moi après quelques modifications.
Voici les fichiers : https://wetransfer.com/downloads/649bd2b6cce38f7a40a457ed8f9b2f2b20210406171734/697e15

Dans ce qui suit, /path/to/ccm désigne le chemin vers le dossier "ccm", lequel contient les deux dossiers "infra" et "symfony".

Pour lancer les containers :
[avion-f16@ccm ~]$ cd /path/to/ccm/infra/
[avion-f16@ccm infra]$ docker-compose up -d



En ouvrant http://localhost/, tu devrais voir la page phpinfo demandé par le fichier /path/to/ccm/symfony/public/index.php


Pour lancer un nouveau projet PHP quelconque :

1. supprimer tout le contenu du dossier /path/to/ccm/symfony/
2. recréer le dossier /path/to/ccm/symfony/public
3. publier les fichiers en tenant compte du fait que http://localhost/fichier.php = /path/to/ccm/symfony/public/fichier.php
4. Si composer doit être utilisé, entrer dans le container "php" :
docker-compose exec php /bin/sh
. Cette commande te placera dans le dossier /var/www du container

Pour lancer un nouveau projet Symfony :

1. supprimer tout le contenu du dossier /path/to/ccm/symfony/
2. entrer dans le container "php" :
docker-compose exec php /bin/sh

3. exécuter
composer create-project symfony/website-skeleton .
dans le dossier /var/www, ce qui créera automatiquement l'arborescence Symfony avec le dossier "public".


Pour lancer ton propre projet Symfony :

1. supprimer tout le contenu du dossier /path/to/ccm/symfony/
2. Placer ton projet dans /path/to/ccm/symfony/ en t'assurant que le dossier "symfony" contienne bien le dossier "public" de ton application Symfony
2. entrer dans le container "php" :
docker-compose exec php /bin/sh

3. exécuter
composer install
depuis /var/www
Super, merci BEAUCOUP ! ça m'a bien aidé :))))))))))))
J'ai encore une petite question si vous avez le temps et qui est peut être liée à l'installation de docker.

j'ai créé un fichier base.html.twig dans le dossier templates de mon projet et un controller qui redirige vers cette page. Mais lorsque je me rend sur mon site j'ai cette erreur : Unable to find template "main/base.html.twig" (looked into: /var/www/templates, /var/www/vendor/symfony/twig-bridge/Resources/views/Form).


Une idée ?
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Bonjour,

Cette erreur indique juste que le template recherché n'est pas là où il devrait être. Vérifie l'emplacement des fichiers, sans oublier que /var/www (dans le container) = le dossier "symfony" en-dehors du container.
Bonjour,

Dans mon projet symfony, il est au bon emplacement. Mais comment vérifier que c'est également le cas dans le dossier hors du container ?
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Si tu demandes le template main/base.html.twig, cela signifie que, en-dehors du container, le fichier
symfony/templates/main/base.html.twig
devrait exister. Est-ce le cas ?
Oui, c'est bien le cas. Je voulais plutôt dire : comment vérifier que c'est également le cas dans le dossier dans le container ?
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Pour rentrer dans le container "php" :

[avion-f16@ccm ~]$ cd /path/to/ccm/infra/
[avion-f16@ccm infra]$ docker-compose up -d
[avion-f16@ccm infra]$ docker-compose exec php /bin/sh
/var/www #


Cela te place dans le dossier /var/www qui correspond au dossier symfony.
La commande ls devrait alors afficher la structure du projet Symfony :

/var/www # ls
bin migrations symfony.lock var
composer.json phpunit.xml.dist templates vendor
composer.lock public tests
config src translations
/var/www #


ls templates/
devrait afficher le dossier "main"
Et
ls templates/main
devrait afficher le fichier base.html.twig
Oui, le fichier apparaît bien dans ce dossier, mais alors d'où vient le problème ?
Problème résolu, il me manquait le composer require symfony/webpack-encore-bundle.

Merci encore pour votre aide :)
Une dernière petite question (je débute vraiment).

J'essaie de créer une base de données sur phpmyadmin avec doctrine. Mais j'ai l'erreur suivante :


In AbstractMySQLDriver.php line 112:

An exception occurred in driver: SQLSTATE[HY000] [2002] Aucune connexion na pu tre tablie car lordinateur cible la expressment refuse.


In Exception.php line 18:

SQLSTATE[HY000] [2002] Aucune connexion na pu tre tablie car lordinateur cible la expressment refuse.


In PDOConnection.php line 39:

SQLSTATE[HY000] [2002] Aucune connexion na pu tre tablie car lordinateur cible la expressment refuse.



----
Pourtant, mon fichier .env est bien configuré : DATABASE_URL="mysql://root:@localhost:3306/todolist"

Voici les conteneurs correspondant dans le docker-compose.yml :

db:
image: mysql
container_name: "db"
restart: always
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
networks:
- dev

phpmyadmin:
image: phpmyadmin
container_name: "phpmyadmin"
restart: always
depends_on:
- db
ports:
- 8080:80
environment:
PMA_HOST: db
PMA_USER: root
networks:
- dev
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Le container "php" exécute le script PHP, et lorsque le script PHP utilise "localhost" pour accéder à la base de données, ça cible donc le container "php" lui-même, or ce dernier ne contient aucun service MySQL.

Docker met en place un système DNS interne qui permet de faciliter les communications entre containers, les containers appartenant au même réseau "dev" peuvent donc résoudre les noms de containers (php, db, ...) par leur adresse IP au sein de ce réseau virtuel. Ainsi, le container "php" qui exécute le code PHP peut traduire "db" par l'IP du container "db".
En résumé : Tu peux utiliser "db" au lieu de "localhost" pour accéder à la base de données depuis le container "php".

Aussi, la base de données todolist doit être créée au préalable, via phpMyAdmin par exemple.
Merci pour cette réponse. J'ai essayé de remplacer localhost par db et j'avais déjà créé ma base de données auparavant mais cela ne change rien.
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Pour ma part, aucun soucis avec

DATABASE_URL="mysql://root@db:3306/todolist"


La commande
php bin/console doctrine:database:create
crée la base de données correctement.
Effectivement, ça fonctionne, je ne devais pas être dans le conteneur php, merci encore :)
Messages postés
10
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
10 avril 2021

Tout fonctionne bien merci encore pour votre aide. J'ai juste une question par rapport au temps d'exécution des requêtes qui est très long à cause de Docker (voir pièces jointes). Auriez-vous une idée pour régler le pb ? Merci

Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
Docker sur Windows en WSL1 se repose sur une machine virtuelle Linux afin de créer ensuite un container Linux (LXC) dans cette VM. Les pertes de performances sont dues à cette VM, pas au container LXC.

Exécuter Docker directement sur un système Linux n'apporte aucune perte de performance notable.

Si tu utilises WSL1, essaie de basculer en WSL2, les performances devraient être meilleures.
Messages postés
10
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
10 avril 2021

J'exécute Docker depuis Powershell et non WSL1 et j'ai déjà basculé en WSL2.
Messages postés
18537
Date d'inscription
dimanche 17 février 2008
Statut
Contributeur
Dernière intervention
10 avril 2021
4 281
> J'exécute Docker depuis Powershell

Tu exécutes en effet Docker à partir de PowerShell mais Docker manipule en arrière-plan une "machine virtuelle" Linux, et c'est dans ce système Linux que les containers sont exécutés. Les containers ne sont pas exécutés dans le PowerShell.

En "schéma" :
1. Le matériel (CPU, RAM, disques, ...)
2. L'OS de base (Windows) où docker / docker-compose sont installés ------
3. Technologie de "virtualisation" (WSL1, WSL2, Hyber-V, ...) |
4. L'OS "virtualisé" (Linux) |
5. Système de containers Linux (LXC) <------ Contrôle --------------------
6. Les containers LXC créés par Docker (php, fpm, mysql, ...)


C'est au niveau de la couche 3 que les pertes de performances sont notables.

Il n'y a pas réellement de solution miracles, pour conserver de bonnes performances, il faut choisir le mode de virtualisation le plus performants (WSL2 semble le mieux) et disposer d'une machine suffisamment puissante pour gérer cette couche de virtualisation. Parfois, le matériel doit aussi prendre en charge des accélérations (Intel VT-x et EPT, AMD-V, ...). Pas besoin d'un monstre, les ordinateurs type i5 / i7 sont suffisant. En-dessous (i3, Celeron, ...), ça devient compliqué.

La méthode efficace pour exécuter des containers Linux reste d'installer Linux directement sur l'ordinateur, sans virtualisation.
Messages postés
10
Date d'inscription
mardi 30 avril 2019
Statut
Membre
Dernière intervention
10 avril 2021

Merci pour vos réponses ! Du coup, pour gagner en vitesse j'ai dupliqué mon projet sur wamp. Mais lorsque j'essaye de me connecter, j'ai l'erreur suivante : variable error doesn't exist. Idem pour la variable {{last_username}}. Celles-ci sont définies dans mon fichier connexion.html.twig. Je ne vois pas d'où cela peut venir.