From aea4e57b9e9c6b76ca9b3df12d42dab3fd1acfb9 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 20:59:11 +0100 Subject: [PATCH 1/8] fix: Vue SPA catch-all takes priority over legacy Twig routes Without priority:1, Symfony matched legacy controllers (e.g. app_activity at /activity) before the vue_app catch-all on hard reload. Now vue_app matches first for all paths except /api/* and /legacy* which still route to Symfony controllers. Co-Authored-By: Claude Sonnet 4.6 --- config/routes.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/routes.yaml b/config/routes.yaml index ceb0599..fed33d3 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -11,4 +11,5 @@ vue_app: template: 'vue/index.html.twig' req: '' requirements: - req: ".*" + req: "^(?!api/|legacy).*" + priority: 1 From 1becbe925486cf9da1de6946b699716625c1bde8 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:11:56 +0100 Subject: [PATCH 2/8] fix: ensure vue_app catch-all is matched before legacy controllers Move vue_app before controllers in routes.yaml AND keep priority:1. Using both guarantees Symfony matches the Vue SPA catch-all first regardless of how the router compiles equal-priority routes. Co-Authored-By: Claude Sonnet 4.6 --- config/routes.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/routes.yaml b/config/routes.yaml index fed33d3..3af1dcd 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -1,9 +1,3 @@ -controllers: - resource: - path: ../src/Controller/ - namespace: App\Controller - type: attribute - vue_app: path: /{req} controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController @@ -13,3 +7,9 @@ vue_app: requirements: req: "^(?!api/|legacy).*" priority: 1 + +controllers: + resource: + path: ../src/Controller/ + namespace: App\Controller + type: attribute From ed86c9074dffc2bb168867eb8c0c97ced098338e Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:13:37 +0100 Subject: [PATCH 3/8] fix: remove unsupported priority key from YAML route definition Symfony's YAML route loader does not support the priority key (only PHP config does). Relying on vue_app being defined first in routes.yaml to ensure it is matched before legacy controller routes. Co-Authored-By: Claude Sonnet 4.6 --- config/routes.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/config/routes.yaml b/config/routes.yaml index 3af1dcd..365bdb7 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -6,7 +6,6 @@ vue_app: req: '' requirements: req: "^(?!api/|legacy).*" - priority: 1 controllers: resource: From 6f3efab0fc9d9ef548d943af230d87fb6f81525e Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:25:30 +0100 Subject: [PATCH 4/8] chore: trigger deploy From c981ce27c5f07fb23a0c74b83486344c4dce7483 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:32:39 +0100 Subject: [PATCH 5/8] test --- assets/vue/app/shared/components/layout/Header.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/vue/app/shared/components/layout/Header.vue b/assets/vue/app/shared/components/layout/Header.vue index f05ca54..a769ca1 100644 --- a/assets/vue/app/shared/components/layout/Header.vue +++ b/assets/vue/app/shared/components/layout/Header.vue @@ -16,7 +16,7 @@
- Mangarr + Mangarrr
From eb25d2c34e971394d472c322f52b0b674b64536e Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:38:40 +0100 Subject: [PATCH 6/8] fix: run cache:clear after docker restart, not before Docker resolves bind mounts at container start time, not dynamically when the Deployer symlink changes. Running cache:clear before restart means docker exec sees the old release code, causing errors on changed config. Co-Authored-By: Claude Sonnet 4.6 --- deploy.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy.php b/deploy.php index cec7df2..580f5b0 100644 --- a/deploy.php +++ b/deploy.php @@ -45,13 +45,13 @@ task('webpack_encore:build', function () { }); // Restart Docker containers (entrypoint gère les migrations automatiquement) -// cache:clear avant restart : le nouveau code est déjà visible via bind mount, -// mais var/ est un volume Docker persistant qui garde l'ancien cache Symfony. +// Le cache:clear est fait APRÈS le restart : Docker résout le bind mount au démarrage +// du container, pas dynamiquement. Avant restart, docker exec voit encore l'ancienne release. desc('Restart Docker containers'); task('docker:restart', function () { - run('docker exec mangarr php bin/console cache:clear --env=prod'); run('docker restart mangarr-worker-commands mangarr-worker-events mangarr-worker-scheduler'); run('docker restart mangarr'); + run('docker exec mangarr php bin/console cache:clear --env=prod'); }); // Pas de PHP sur l'hôte : désactiver les tâches Symfony qui en ont besoin From 2a8b6bc3970187b12712fc5838040816ea8dad4a Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 21:56:23 +0100 Subject: [PATCH 7/8] feat: deploy optimisation --- config/packages/webpack_encore.yaml | 10 ++-- deploy.php | 83 ++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/config/packages/webpack_encore.yaml b/config/packages/webpack_encore.yaml index 4c009ee..cc50b57 100644 --- a/config/packages/webpack_encore.yaml +++ b/config/packages/webpack_encore.yaml @@ -34,11 +34,11 @@ framework: assets: json_manifest_path: '%kernel.project_dir%/public/build/manifest.json' -#when@prod: -# webpack_encore: -# # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes) -# # Available in version 1.2 -# cache: true +when@prod: + webpack_encore: + # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes) + # Available in version 1.2 + cache: true #when@test: # webpack_encore: diff --git a/deploy.php b/deploy.php index 580f5b0..cbd6aa3 100644 --- a/deploy.php +++ b/deploy.php @@ -9,9 +9,9 @@ set('repository', "https://{$giteaToken}@git.homelab.nestor-server.fr/colgora/Ma set('keep_releases', 3); set('composer_options', '--no-dev --optimize-autoloader --no-interaction --prefer-dist --ignore-platform-reqs --no-scripts'); -// Copier vendor/ et node_modules/ depuis la release précédente (hard links, quasi instantané) -// Composer et npm ne mettent à jour que ce qui a changé → déploiements beaucoup plus rapides -set('copy_dirs', ['vendor', 'node_modules']); +// Copier vendor/ depuis la release précédente (hard links, quasi instantané) +// node_modules est géré par le shared mount /srv/mangarr/shared/node_modules +set('copy_dirs', ['vendor']); // Pas de shared_files ni shared_dirs : tout est géré par les volumes Docker set('shared_files', []); @@ -31,17 +31,86 @@ task('deploy:prepare_dirs', function () { // composer install via container éphémère (pas de PHP sur l'hôte requis) // --user assure que vendor/ appartient au user deploy et non root +// Skip si composer.lock inchangé et vendor/ déjà populé (hard-linké depuis la release précédente) task('deploy:vendors', function () { + $releaseDir = get('release_path'); + $previousDir = get('previous_release'); + + if ($previousDir !== null) { + $lockUnchanged = test("diff -q $previousDir/composer.lock $releaseDir/composer.lock > /dev/null 2>&1"); + $vendorPopulated = test("[ -d $releaseDir/vendor/composer ]"); + + if ($lockUnchanged && $vendorPopulated) { + writeln('deploy:vendors skipped — composer.lock unchanged'); + return; + } + } + run('docker run --rm --user $(id -u):$(id -g) -v {{release_path}}:/app -w /app composer:2 install {{composer_options}}'); }); // Build assets via container node éphémère -// Le cache webpack (node_modules/.cache) est persisté dans shared/webpack_cache entre les releases -// → 1er build lent, suivants compilent uniquement les modules modifiés +// 3 couches d'optimisation : +// 1. Skip total si aucun fichier front-end n'a changé (hard-link public/build/) +// 2. Skip npm install si package-lock.json inchangé (node_modules partagé persistant) +// 3. Cache npm et webpack persistants entre les releases desc('Build Webpack Encore assets'); task('webpack_encore:build', function () { - run('mkdir -p /srv/mangarr/shared/webpack_cache'); - run('docker run --rm --user $(id -u):$(id -g) -e npm_config_cache=/tmp/npm-cache -e PUPPETEER_SKIP_DOWNLOAD=1 -v {{release_path}}:/app -v /srv/mangarr/shared/webpack_cache:/app/node_modules/.cache -w /app node:22-alpine sh -c "npm install && npm run build"'); + $sharedDir = '/srv/mangarr/shared'; + $sharedWebpackCache = "$sharedDir/webpack_cache"; + $sharedNodeModules = "$sharedDir/node_modules"; + $sharedNpmCache = "$sharedDir/npm_cache"; + + run("mkdir -p $sharedWebpackCache $sharedNodeModules $sharedNpmCache"); + + $releaseDir = get('release_path'); + $previousDir = get('previous_release'); // null au 1er déploiement + + // --- COUCHE 1 : skip total si aucun fichier front-end n'a changé --- + if ($previousDir !== null) { + $watchList = ['assets', 'templates', 'package.json', 'package-lock.json', + 'webpack.config.js', 'postcss.config.js', 'tailwind.config.js']; + + $diffChecks = implode(' && ', array_map( + fn($p) => "diff -rq --no-dereference $previousDir/$p $releaseDir/$p > /dev/null 2>&1", + $watchList + )); + + $hasPreviousBuild = test("[ -d $previousDir/public/build ] && [ -f $previousDir/public/build/manifest.json ]"); + + if ($hasPreviousBuild && test("($diffChecks)")) { + run("cp -al $previousDir/public/build $releaseDir/public/build"); + writeln('webpack_encore:build skipped — no front-end files changed'); + return; + } + } + + // --- COUCHE 2 : skip npm install si package-lock.json inchangé --- + $needsNpmInstall = true; + if ($previousDir !== null) { + $lockUnchanged = test("diff -q $previousDir/package-lock.json $releaseDir/package-lock.json > /dev/null 2>&1"); + $nmPopulated = test("[ -d $sharedNodeModules/.bin ]"); + if ($lockUnchanged && $nmPopulated) { + $needsNpmInstall = false; + } + } + + // --- COUCHE 3 : build docker avec caches persistants --- + $installCmd = $needsNpmInstall + ? 'npm install --prefer-offline && npm run build' + : 'npm run build'; + + run("docker run --rm \ + --user \$(id -u):\$(id -g) \ + -v $releaseDir:/app \ + -v $sharedNodeModules:/app/node_modules \ + -v $sharedWebpackCache:/app/node_modules/.cache \ + -v $sharedNpmCache:/npm_cache \ + -e npm_config_cache=/npm_cache \ + -e PUPPETEER_SKIP_DOWNLOAD=1 \ + -w /app \ + node:22-alpine \ + sh -c '$installCmd'"); }); // Restart Docker containers (entrypoint gère les migrations automatiquement) From ff8b9450143407c59878d39fff116da9639f1381 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Wed, 11 Mar 2026 22:00:43 +0100 Subject: [PATCH 8/8] fix: test deploy --- assets/vue/app/shared/components/layout/Header.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/vue/app/shared/components/layout/Header.vue b/assets/vue/app/shared/components/layout/Header.vue index a769ca1..f05ca54 100644 --- a/assets/vue/app/shared/components/layout/Header.vue +++ b/assets/vue/app/shared/components/layout/Header.vue @@ -16,7 +16,7 @@
- Mangarrr + Mangarr