Depuis un peu plus d'un an maintenant, j'utilise DDEV dès que j'ai besoin de mettre en place un environnement de développement. Grâce à un simple fichier .yaml
, cet outil très pratique est capable de fournir un espace de travail en conteneur avec PHP, une base de données MariaDB/PostreSQL, et Mailpit. C'est parfait pour des projets de toute taille, du simple site vitrine WordPress à l'application Symfony la plus complexe. Cependant, il n'est pas vraiment conçu pour être utilisé avec Node par défaut. Tout du moins, même s'il embarque Node de base, si vous souhaitez utiliser un backend PHP avec un frontend en TypeScript, cela demande un peu de configuration, comme nous allons le voir dans cet article. Il est inspiré de celui d'Andy Blum sur le blog de Lullabot. Mon approche est similaire, mais simplifiée.
Ma stack web de prédilection est Symfony en mode API (soit en RESTful ou avec GraphQL) et un frontend qui utilise Vue.js. J'utilisais auparavant NVM ou Volta avec une version de Node installée localement, mais je désirais quelque chose de totalement portable - quelque chose où je peux simplement cloner un dépôt, lancer ddev start
et me mettre au travail. Pour cela, nous allons suivre les étapes suivantes :
- Mettre en place le conteneur PHP et Symfony
- Geler la version de Node et installer Vue.js
- Ajouter un reverse proxy pour accéder au frontend
- Améliorer la DX grâce à un Makefile
Pour ce projet, nous allons utiliser un domaine fictif - disons tinydev.ddev.site
- et avoir l'API sur api.tinydev.ddev.site
et l'app web sur app.tinydev.ddev.site
. Je pars du principe que vous avez déjà Docker et DDEV installé et prêt à l'emploi.
Pour que les choses soient bien rangées, nous allons utiliser la structure de dossier suivante :
/.ddev
- config.yaml
/backend
- Le projet Symfony...
/webapp
- Le projet Vue.js...
Le dossier .ddev
va contenir le fichier de configuration de DDEV (config.yaml
), l'API Symfony sera dans /backend
et l'app front sera dans /webapp
.
Mise en place de l'app Symfony
Commençons par initialiser le projet grâce à ddev config
, en prenant soin de sélectionner symfony
comme type d'application. Le docroot pour notre projet sera backend/public
.
Une fois configuré, ouvrez /.ddev/config.yaml
et ajoutez les hosts additionels (api.tinydev
et app.tinydev
). Le fichier de configuration devrait ressembler à ceci :
name: tinydev
type: symfony
docroot: backend/public
php_version: '8.3'
webserver_type: nginx-fpm
xdebug_enabled: false
additional_hostnames: ['api.tinydev', 'app.tinydev']
additional_fqdns: []
database:
type: mariadb
version: '10.11'
use_dns_when_possible: true
composer_version: '2'
web_environment: []
corepack_enable: false
Démarrez DDEV avec ddev start
, et entrez dans le conteneur grâce à ddev ssh
. Nous allons installer Symfony dans le dossierbackend
(au moment où j'écris ces lignes la dernière version de Symfony est la 7.2). Nous allons devoir effacer le dossier backend
pour que Composer puisse l'initialiser correctement.
> rm -rf backend && composer create-project symfony/skeleton:"7.2.x" backend
Une fois installé, créez un contrôleur simple pour vérifier que tout fonctionne correctement :
<?php
// /backend/src/Controller/HomeController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HomeController extends AbstractController
{
#[Route('/')]
public function index()
{
return new Response("Hello, World!");
}
}
Vous pouvez naviguer à l'adresse https://tinydev.ddev.site
et vous devriez voir le message « Hello, World! ». Si ce n'est pas le cas, n'hésitez pas à redémarrer DDEV avec ddev restart
.
À ce moment, https://api.tinydev.ddev.site
pointe toujours vers l'application Symfony. Nous allons régler cela tout de suite.
Geler la version de Node et installer Vue.js
Par défaut, DDEV embarque Node v22. Nous allons geler cette version pour éviter les mauvaises surprises pendant la phase de développement. Cela peut être fait très facilement dans /.ddev/config.yaml
nodejs_version: '22'
Redémarrez DDEV (ddev restart
) et entrez dans le conteneur avec ddev ssh
. Nous allons maintenant installer Vue.js dans le dossier webapp
:
> npm create vue@latest
Choisissez les options qui vous conviennent, mais spécifiez webapp
comme nom de projet, car c'est ce nom qui sera utilisé comme dossier de destination pour les fichiers de l'app Vue.js. Vous pouvez ensuite installer l'application elle-même :
> cd webapp && npm install
Naviguons maintenant vers https://app.tinydev.ddev.site
pour voir... rien ? C'est normal. L'app est installée, mais elle n'est pas encore accessible.
Ajouter un reverse proxy pour accéder au frontend
Pour solutioner ce problème, nous allons ajouter un fichier de configuration nginx dans /.ddev/nginx_full/app.tinydev.conf
:
server {
server_name app.tinydev.ddev.site;
location / {
proxy_pass http://localhost:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/certs/master.crt;
ssl_certificate_key /etc/ssl/certs/master.key;
include /etc/nginx/monitoring.conf;
error_log /dev/stdout info;
access_log /var/log/nginx/access.log;
include /etc/nginx/common.d/*.conf;
include /mnt/ddev_config/nginx/*.conf;
}
Nous devons aussi éditer vite.config.ts
pour autoriser ce nouvel hôte :
// /webapp/vite.config.ts
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueDevTools from 'vite-plugin-vue-devtools';
export default defineConfig({
server: {
allowedHosts: ['app.tinydev.ddev.site'],
},
plugins: [vue(), vueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
});
Redémarrez DDEV à nouveau (ddev restart
), allez dans le conteneur (ddev ssh
), et lancez npm run dev
dans le dossier /webapp
. N'oubliez pas d'exécuter npm install
si cela n'est pas déjà fait.
Si vous naviguez désormais sur https://app.tinydev.ddev.site
, vous devriez voir la page de présentation par défaut d'un nouveau projet Vite.
Vous avez désormais un projet utilisant Symfony et Vue.js, et entièrement conteneurisé grâce à DDEV ! Félicitations ! 🎉
Vous pouvez maintenant accéder à votre web app sur https://app.tinydev.ddev.site
, en effectuant des appels à votre API qui se trouve sur https://api.tinydev.ddev.site
.
Finissons ce tutoriel en ajoutant un peu de magie pour améliorer notre DX grâce à un simple fichier Makefile.
Améliorer la DX grâce à un Makefile
Devoir entrer dans le conteneur à chaque fois que nous voulons lancer le serveur web Vite peut rapidement devenir contraignant. De même, il serait bien plus pratique de ne pas avoir à le faire dès que nous voulons lancer des commandes symfony comme lancer une migration ou vider le cache. Heureusement, nous pouvons nous faciliter la tâche avec un Makefile et des raccourcis très pratiques :
Important : Pensez à utiliser des tabs (et non des espaces) pour l'indentation de votre fichier !
# /Makefile
WEBAPP_FOLDER=/var/www/html/webapp
API_FOLDER=/var/www/html/backend
start:
ddev start
stop:
ddev stop
up: start
ddev exec --dir $(WEBAPP_FOLDER) npm run dev
cache-clear:
ddev exec --dir $(API_FOLDER) php bin/console cache:clear
cc: cache-clear
migration:
ddev exec --dir $(API_FOLDER) php bin/console make:migration
Gardez à l'esprit que vous devrez tout de même utiliser ddev ssh
pour exécuter des commandes Composer, car ddev composer
s'exécute à la racine du projet par défaut.
Et voilà ! Un environnement de développement simple et portable que vous pouvez utiliser n'importe où et partager avec d'autres.
Happy coding!