4.7 KiB
3. Architecture technique
Trois couches, chacune volontairement minimale :
- Base de données : MySQL (base ASPIC, utilisateur dédié crm_user — même logique que pour les autres applications du VPS : un compte limité à sa base plutôt que root).
- API : quelques fichiers PHP (PDO) exposant le CRUD contacts en JSON, packagés dans un conteneur léger (image officielle php:8.3-apache + extensions pdo_mysql / mysqli).
- Frontend : un seul fichier index.html en JavaScript vanilla — pas de build, pas de dépendance, tableau + formulaire d'ajout/modification/suppression appelant l'API en fetch().
Recette de déploiement réutilisable
Pour éviter de redécouvrir les mêmes pièges, la recette suivante (validée sur une précédente application PHP du VPS) a été réutilisée telle quelle : image officielle + extensions installées à chaud au démarrage (plutôt qu'un Dockerfile/build:, non testé sur ce Docker Manager), et un service SFTP dédié pour déposer les fichiers, avec le chown fait par le conteneur applicatif lui-même à chaque démarrage (plus fiable qu'un conteneur de correction de permissions séparé, dont l'ordre de démarrage n'est pas garanti sur cette interface).
docker-compose.yml (situé dans /docker/aspic/ sur le VPS — chemin confirmé le 30 août 2026, voir section 23)
services:
crm-app:
image: 'php:8.3-apache'
restart: unless-stopped
command: >
bash -c "chown -R 1001:1001 /var/www/html && docker-php-ext-install pdo_mysql mysqli && apache2-foreground"
environment:
DB_HOST: "mysql"
DB_NAME: "ASPIC"
DB_USER: "crm_user"
DB_PASS: "***"
BREVO_API_KEY: "***"
LIEN_DOC_CLE_SECRETE: "***"
ROUTER_DB_HOST: "mysql2"
ROUTER_DB_USER: "crm_user"
ROUTER_DB_PASS: "***"
volumes:
- ./src:/var/www/html
networks:
- proxy
sftp:
image: atmoz/sftp:latest
restart: unless-stopped
volumes:
- ./src:/home/jeanmarc/www
ports:
- "2224:22"
command: jeanmarc:***:1001::www
networks:
proxy:
external: true
BREVO_API_KEY et LIEN_DOC_CLE_SECRETE ajoutées le 26 août 2026 (voir section 18) — renseignées et déployées le jour même, fonctionnelles en production. ROUTER_DB_HOST/ROUTER_DB_USER/ROUTER_DB_PASS ajoutées le 30 août 2026 (voir section 24, MIRADOR) — connexion vers l'instance mysql2 qui héberge désormais MIRADOR.
Convention de nommage et de livraison des fichiers (actée le 21 août 2026)
Déployer consiste à copier dans le répertoire de l'application (le volume ./src monté dans le conteneur, voir docker-compose.yml ci-dessus) les fichiers finaux de celle-ci. Convention de livraison actée : Claude livre désormais les fichiers sous leur nom final "propre", sans préfixe (identification.html, liste_contacts.html, aspic.php, contacts.php, db.php) — les anciens préfixes (ASPIC_ecran_, aspic_) utilisés en début de projet sont abandonnés. Jean-Marc conserve de son côté l'habitude d'incrémenter un numéro de version derrière chaque fichier reçu pour garder un historique, et fait lui-même le renommage final (y compris le passage .html → .php le cas échéant) au moment du transfert FTP. Depuis le 30 août 2026 (section 23), ce dossier ./src est aussi directement la copie de travail du dépôt Git — voir cette section pour le nouveau circuit de livraison/versionnage.
Points d'attention retenus pour une prochaine application PHP
- UID 1001 (pas 0/root) pour l'utilisateur SFTP — un compte root est bloqué en authentification par mot de passe par la configuration SSH par défaut de l'image.
- Mot de passe SFTP : éviter les caractères spéciaux actifs en shell (
: , * $ \& | ; < > ( )` guillemets, espace) — préférer un mot de passe purement alphanumérique. - Faire le chown directement dans la commande de démarrage du conteneur applicatif (pas via un conteneur séparé) : plus robuste, ne dépend pas de l'ordre de démarrage entre conteneurs.
- Repartir sur un dossier de données neuf en cas de comportement erratique persistant (permissions, authentification) plutôt que de s'acharner sur un dossier qui a accumulé plusieurs changements de configuration.
- Un conteneur avec un volume bind-mount (
./chemin:/dans/le/conteneur) reste attaché à l'objet-dossier présent sur l'hôte au moment de son démarrage. Si ce dossier est renommé/recréé sur l'hôte (ex.mv dossier dossier_oldpuis recréation d'undossierneuf) pendant que le conteneur tourne, celui-ci continue de voir l'ancien contenu jusqu'à son redémarrage — voir le piège rencontré en section 23 avec le conteneur SFTP.