Système de gestion de traductions pensé en CMS headless : un back-office pour ceux qui traduisent, une API pour ce qui consomme. Architecture - Symfony 7.4 / API Platform 4.3 / MariaDB 11.4, SPA React 19 servie en même origine — ce qui rend viable le cookie de session plutôt qu'un jeton en localStorage. - Deux APIs séparées : Management (session ou clé) et Delivery (stateless, clé seule). Les fusionner ferait porter à chaque lecture de bundle le coût de la session. - Stockage canonique en ICU MessageFormat, sérialisation par plateforme. Le format d'une plateforme ne contamine pas la base. - Publication par releases immuables ; le déploiement est un déplacement de pointeur, donc le rollback aussi. - Isolation multi-organisation par filtre Doctrine, avec un test d'architecture qui casse la CI si une entité échappe à l'invariant. Éditeur, deux vues - Par langue : source et cible, jamais douze colonnes. Grille virtualisée, saisie sans bouton « Enregistrer », panneau de contexte permanent. - Par clé : une clé, toutes ses langues empilées et repliées. Répond à « ce libellé est-il prêt partout ? ». - Mode Focus dans les deux : une file à vider, ⌘↵ pour enchaîner. - Le traducteur ne voit jamais d'ICU : pastilles de variables, un champ par catégorie CLDR de la langue cible. Administration - Deux niveaux : projet (membres, clés API, plateformes) et organisation (annuaire des comptes, création de projets). - Invitations par e-mail, jeton 256 bits stocké haché. - Désactiver un compte coupe les sessions en cours, pas seulement les connexions suivantes. - Les plateformes s'archivent ; ni elles ni les environnements ne se suppriment — la trace explique pourquoi telle clé existe. CLI tqs - PHAR autonome de 3 Mo, autoloader généré : le dépôt client ne dépend ni de Composer ni de la disponibilité de TQ-Slator. - init / push / pull / status ; le sync est non destructif par défaut et son prune est scopé plateforme. 126 tests, PHPStan niveau 8. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
104 lines
5.2 KiB
Docker
104 lines
5.2 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# PHP 8.4 et non 8.5 : c'est la version contre laquelle Composer résout les
|
|
# dépendances (voir config.platform dans composer.json). L'hôte de dev peut être
|
|
# en 8.5 sans que cela change ce qui sera déployé.
|
|
ARG PHP_VERSION=8.4
|
|
ARG FRANKENPHP_VERSION=1
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# base — runtime commun dev/prod
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
FROM dunglas/frankenphp:${FRANKENPHP_VERSION}-php${PHP_VERSION} AS app_base
|
|
|
|
WORKDIR /app
|
|
|
|
# `acl` sert au setfacl sur var/ ; `gettext` fournit envsubst utilisé par l'entrypoint.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
acl \
|
|
file \
|
|
gettext \
|
|
git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
RUN install-php-extensions \
|
|
@composer \
|
|
apcu \
|
|
intl \
|
|
opcache \
|
|
pdo_mysql \
|
|
redis \
|
|
zip
|
|
|
|
ENV COMPOSER_ALLOW_SUPERUSER=1
|
|
ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d"
|
|
|
|
COPY --link frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/
|
|
COPY --link frankenphp/Caddyfile /etc/frankenphp/Caddyfile
|
|
|
|
ENTRYPOINT ["docker-php-entrypoint"]
|
|
CMD ["frankenphp", "run", "--config", "/etc/frankenphp/Caddyfile"]
|
|
|
|
HEALTHCHECK --interval=10s --timeout=3s --start-period=45s --retries=5 \
|
|
CMD curl -fsS http://localhost:2019/metrics || exit 1
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# dev — sources montées en volume, pas copiées
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
FROM app_base AS app_dev
|
|
|
|
# APP_ENV n'est volontairement PAS défini ici. Le fichier .env fournit déjà
|
|
# `dev` par défaut, et une variable d'environnement réelle prendrait le pas sur
|
|
# le réglage de phpunit.dist.xml : `bin/phpunit` tournerait alors en dev, où le
|
|
# service test.service_container n'existe pas.
|
|
ENV XDEBUG_MODE=off
|
|
|
|
COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
|
|
|
|
RUN install-php-extensions xdebug
|
|
|
|
# Pas de composer install ici : le volume monté par Compose écraserait vendor/.
|
|
# L'entrypoint s'en charge au démarrage du conteneur.
|
|
COPY --link docker/entrypoint.dev.sh /usr/local/bin/entrypoint.dev.sh
|
|
RUN chmod +x /usr/local/bin/entrypoint.dev.sh
|
|
|
|
# CMD doit être redéclaré : Docker le remet à zéro dès qu'un étage redéfinit
|
|
# ENTRYPOINT, même si l'étage de base en fournissait un.
|
|
ENTRYPOINT ["docker-php-entrypoint", "entrypoint.dev.sh"]
|
|
CMD ["frankenphp", "run", "--config", "/etc/frankenphp/Caddyfile"]
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# vendor — couche de dépendances isolée pour maximiser le cache de build
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
FROM app_base AS app_vendor
|
|
|
|
COPY --link composer.json composer.lock symfony.lock ./
|
|
|
|
RUN --mount=type=cache,target=/tmp/composer \
|
|
composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# prod — image finale, worker mode activé
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
FROM app_base AS app_prod
|
|
|
|
ENV APP_ENV=prod
|
|
ENV APP_RUNTIME="Runtime\FrankenPhpSymfony\Runtime"
|
|
# Active le worker mode : le kernel Symfony reste en mémoire entre les requêtes.
|
|
# C'est ce qui met la Delivery API sous les 20 ms.
|
|
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
|
|
|
|
COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/
|
|
COPY --from=app_vendor --link /app/vendor ./vendor
|
|
COPY --link . ./
|
|
|
|
RUN set -eux; \
|
|
mkdir -p var/cache var/log var/storage; \
|
|
composer dump-autoload --classmap-authoritative --no-dev; \
|
|
composer dump-env prod; \
|
|
composer run-script --no-dev post-install-cmd; \
|
|
chmod +x bin/console; \
|
|
setfacl -R -m u:www-data:rwX -m u:root:rwX var; \
|
|
setfacl -dR -m u:www-data:rwX -m u:root:rwX var
|
|
|
|
VOLUME /app/var/storage
|