- .env, .env.test, ansible/env.local.j2: point SONARQUBE_URL to https://sn.e-cosplay.fr
- ansible/vault.yml, .env: rotate sonarqube_badge_token to new value
- .gitea/workflows/ci.yml, sonarqube.yml: remove OWASP Dependency-Check steps and force sonar.host.url via CLI args
- sonar-project.properties: drop dependencyCheck report paths
- .gitea/workflows/deploy.yml: switch SSH target from 34.90.187.4 to 152.228.222.133
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sur le serveur prod, l'utilisateur 'bot' (cree par Ansible) a UID 1001
alors que l'utilisateur 'appuser' du conteneur PHP etait hardcode a UID 1000,
ce qui causait des erreurs 'Unable to write in var/cache/prod' apres restore
ou deploiement: les fichiers du host appartenaient a bot:bot (1001) et
appuser (1000) ne pouvait pas y ecrire.
docker/php/prod/Dockerfile:
- appuser UID/GID passe de 1000 a 1001 pour matcher bot
- dev/Dockerfile reste a 1000 (les users dev sont generalement 1000)
ansible/deploy.yml:
- chown des dossiers public/uploads/* et var/payouts passe de 1000 a 1001
restore.sh:
- Nouvelle option --owner USER:GRP (defaut: bot:bot, override via RESTORE_OWNER)
- Chown automatique en fin de restore sur var/, public/uploads/, config/cert/, .env.local
- Purge automatique de var/cache (sera reconstruit par PHP)
- Verification root au demarrage (sudo requis pour chown)
- Verification de l'existence du user et group cibles
- Option --skip-chown pour bypass (deconseille)
- Etapes post-migration mises a jour (ajout de make build_prod en premier)
Procedure de migration sur le serveur apres ce commit:
cd /var/www/e-ticket
git pull origin master
make build_prod # rebuild image PHP avec UID 1001
make stop_prod
sudo chown -R bot:bot var public/uploads config/cert .env.local
sudo rm -rf var/cache
make start_prod
make clear_prod
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevents stale Doctrine L2 cache and app cache from causing issues
after schema changes. Clears both filesystem cache and Redis pool.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New SECRET_ANALYTICS variable replaces kernel.secret for analytics
- Ansible generates a random 32-char secret at each deploy
- Endpoint token and encryption key change with every deployment
- Existing sessions will get new visitor_id after deploy (expected)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The /admin/infra page was slow because Docker stats API blocks per container.
Now a cron (every 5min) generates var/infra.json via app:infra:snapshot,
and the page reads the static JSON file instantly.
Mount Docker socket in cron container for snapshot access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The PHP container user needs the docker group to read the socket.
Uses DOCKER_GID env var in dev (defaults to 989) and dynamic GID
detection via Ansible stat in prod.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete rewrite of /admin/infra into 4 columns:
- Col 1 (Serveur): CPU, RAM, Disk, System, Services (Caddy, Docker, SSL cert)
- Col 2 (Containers): All Docker containers with CPU%, RAM, state via Docker API
- Col 3 (Redis): Global stats + per-DB (Messenger, Sessions, Cache)
- Col 4 (PostgreSQL): Instance stats + PgBouncer pools/stats
Extract all infra logic into InfraService. Mount Docker socket (read-only)
in PHP container for container stats. Check SSL cert expiry and Caddy status.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without admin_users/stats_users, connecting to the pgbouncer virtual
database fails with "database pgbouncer does not exist".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Configure Redis DB 2 as Symfony cache adapter
- Cache Meilisearch search results for 5 minutes (invalidated on writes)
- Cache admin dashboard stats for 10 minutes
- Add invalidateSearchCache() called after each Meilisearch write
- Update tests to support cache mock injection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The getmeili/meilisearch image (Debian slim) has neither curl nor wget,
so healthcheck commands always fail. Use condition: service_started
and rely on Messenger retry mechanism for brief startup delays.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The getmeili/meilisearch image does not include curl, causing the
healthcheck to fail and blocking messenger startup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add toggle online/offline and delete routes in AdminController
- Add action buttons (En ligne, Modifier, Supprimer) in admin events template
- Bypass requireEventOwnership and requireStripeReady for ROLE_ROOT so admin can edit any event
- Add Meilisearch healthcheck and depends_on in messenger service (prod + dev)
- Add tests for all new admin routes and ROLE_ROOT bypass
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove Start/Wait/Translate LibreTranslate tasks from deploy.yml
- Add SESSION_HANDLER_DSN with Redis in env.local.j2 for prod sessions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix SESSION_HANDLER_DSN: use Redis db index (/1) instead of /sessions
which caused "dbindex must be a number" error
- Remove LibreTranslate service and volume from docker-compose prod
- Remove gitignore rules for translation files (en, es, de, it)
so all languages are tracked in git
- Apply PHP CS Fixer style fixes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ApiSandboxController: reduce scan() returns from 4 to 3 via ternary
- ApiDocController: add MIME_JSON constant, extract buildInsomniaRequest()
and buildInsomniaBody() to reduce cognitive complexity
- Store sessions in Redis to fix SSO disconnect with 2 PHP replicas
(round-robin load balancing caused session loss on filesystem storage)
- Configure session cookie: 24h lifetime, secure auto, samesite lax
- Replace Caddy analytics proxies (/stats/*, /assets/perf.js, /sperf)
with direct URLs to tools-security.esy-web.dev and cloudflareinsights.com
- Update JS tests for new direct analytics URLs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ansible: healthcheck via PHP container (curl from php, not libretranslate)
- Ansible: exit 0 if LibreTranslate not ready (don't block deploy)
- Ansible: ignore_errors on translation step (non-blocking)
- AccountControllerTest: add testEventQrCode (PNG response) and testEventQrCodeDeniedForOtherUser (403)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- TranslateCommand: increase waitForApi retries from 30 to 90 (3 minutes total)
- Ansible deploy: add explicit healthcheck wait step (60×5s = 5min max) before translation
- First launch downloads ~2-4GB of language models, needs more time
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Separate webhook routes with different secrets
- Add verifyConnectWebhookSignature() to StripeService
- Add STRIPE_WEBHOOK_SECRET_CONNECT env var
- Update vault with prod secrets for both endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create unavailable.html static page with neo-brutalist design and retry button
- Add handle_errors in Caddy for 502/503: serve unavailable.html
- Add dial/read/write timeouts to php_fastcgi (5s/30s/30s)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- sw.js regenerated by Workbox with full cache strategies
- Add screen.png, site.webmanifest, workbox/*, idb/*, pwa/* to Caddy static paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add favicon.png link and apple-touch-icon in base.html.twig
- Add theme-color meta tag (#fabf04)
- Add pwa_dev and pwa_prod Makefile commands
- Add PWA asset generation step in Ansible playbook after cache clear
- Update Caddy static paths for favicon.png, marker.png, manifest.json, sw.js
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Store smime_private_key in encrypted vault
- Add playbook tasks: create cert directory + deploy private key with 0600 permissions
- Certificate public already in git at config/cert/certificate.pem
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>