Story 1.1: initialisation projet
This commit is contained in:
333
docs/stories/1.4.page-canary-deploiement.md
Normal file
333
docs/stories/1.4.page-canary-deploiement.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# Story 1.4: Page Canary et Validation du Déploiement
|
||||
|
||||
## Status
|
||||
|
||||
In Progress
|
||||
|
||||
## Story
|
||||
|
||||
**As a** développeur,
|
||||
**I want** déployer une page "canary" minimale sur le serveur,
|
||||
**so that** je valide que l'infrastructure PHP et le CSS fonctionnent en production.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. La page index.php affiche un message de test stylé avec Tailwind (titre centré, couleur d'accent)
|
||||
2. La page est responsive (vérifiable sur mobile)
|
||||
3. Le déploiement sur le serveur personnel fonctionne
|
||||
4. Le site est accessible via HTTPS
|
||||
5. Le temps de chargement est inférieur à 2 secondes (Lighthouse)
|
||||
6. Les fichiers sensibles ne sont pas accessibles (.env, vendor/, data/)
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [] **Task 1 : Finaliser la page canary** (AC: 1, 2)
|
||||
- [] Mettre à jour `index.php` avec un contenu de test attractif
|
||||
- [] Ajouter un titre centré avec la classe `text-primary`
|
||||
- [] Ajouter un sous-titre et une description
|
||||
- [] Vérifier le responsive sur mobile (DevTools)
|
||||
- [] Tester les classes Tailwind (btn-primary, card, etc.)
|
||||
|
||||
- [] **Task 2 : Préparer les fichiers pour le déploiement** (AC: 3)
|
||||
- [] Exécuter `npm run build` pour générer le CSS minifié
|
||||
- [] Exécuter `composer install --no-dev` pour les dépendances
|
||||
- [ ] Créer le fichier `.env` de production (à faire sur le serveur)
|
||||
- [] Vérifier que `.gitignore` exclut les fichiers sensibles
|
||||
|
||||
- [ ] **Task 3 : Configurer le serveur nginx** (AC: 3, 4, 6)
|
||||
- [ ] Créer/adapter la configuration nginx
|
||||
- [ ] Configurer les redirections vers index.php (front controller)
|
||||
- [ ] Bloquer l'accès aux fichiers sensibles (.env, vendor/, data/, logs/)
|
||||
- [ ] Configurer les headers de sécurité
|
||||
- [ ] Activer la compression gzip
|
||||
|
||||
- [ ] **Task 4 : Configurer HTTPS** (AC: 4)
|
||||
- [ ] Vérifier le certificat SSL (Let's Encrypt)
|
||||
- [ ] Configurer la redirection HTTP → HTTPS
|
||||
- [ ] Tester l'accès HTTPS
|
||||
|
||||
- [ ] **Task 5 : Déployer sur le serveur** (AC: 3)
|
||||
- [ ] Transférer les fichiers (FTP/SFTP ou git pull)
|
||||
- [ ] Exclure : `node_modules/`, `package.json`, `package-lock.json`, `tailwind.config.js`, `postcss.config.js`
|
||||
- [ ] Vérifier les permissions des dossiers
|
||||
- [ ] Tester l'accès à la page
|
||||
|
||||
- [ ] **Task 6 : Valider les performances** (AC: 5)
|
||||
- [ ] Lancer un audit Lighthouse
|
||||
- [ ] Vérifier que le temps de chargement < 2s
|
||||
- [ ] Vérifier le score Performance > 90
|
||||
- [ ] Corriger les éventuels problèmes
|
||||
|
||||
- [ ] **Task 7 : Tests de sécurité** (AC: 6)
|
||||
- [ ] Tester l'accès à `/.env` → doit retourner 404
|
||||
- [ ] Tester l'accès à `/vendor/` → doit retourner 404
|
||||
- [ ] Tester l'accès à `/data/` → doit retourner 404
|
||||
- [ ] Tester l'accès à `/logs/` → doit retourner 404
|
||||
|
||||
## Dev Notes
|
||||
|
||||
### Contenu Page Canary (index.php)
|
||||
|
||||
```php
|
||||
<?php
|
||||
// index.php - Page Canary
|
||||
|
||||
require_once __DIR__ . '/includes/functions.php';
|
||||
|
||||
include_template('header', [
|
||||
'pageTitle' => 'Portfolio en construction',
|
||||
'pageDescription' => 'Mon portfolio de développeur web arrive bientôt. Restez connectés !'
|
||||
]);
|
||||
?>
|
||||
|
||||
<main class="min-h-screen flex items-center justify-center">
|
||||
<div class="container-content text-center py-20">
|
||||
<!-- Titre principal -->
|
||||
<h1 class="text-display text-text-primary mb-4 animate-fade-in">
|
||||
Portfolio <span class="text-primary">en construction</span>
|
||||
</h1>
|
||||
|
||||
<!-- Sous-titre -->
|
||||
<p class="text-xl text-text-secondary mb-8 max-w-2xl mx-auto animate-fade-in animation-delay-100">
|
||||
Je prépare quelque chose de génial pour vous.
|
||||
<br>Revenez bientôt pour découvrir mes projets !
|
||||
</p>
|
||||
|
||||
<!-- Badge de test -->
|
||||
<div class="flex justify-center gap-4 mb-12 animate-fade-in animation-delay-200">
|
||||
<span class="badge">PHP</span>
|
||||
<span class="badge">Tailwind CSS</span>
|
||||
<span class="badge badge-primary">En cours</span>
|
||||
</div>
|
||||
|
||||
<!-- Card de test -->
|
||||
<div class="card max-w-md mx-auto animate-fade-in animation-delay-300">
|
||||
<div class="card-body">
|
||||
<h3 class="text-subheading mb-2">Infrastructure validée</h3>
|
||||
<p class="text-text-secondary mb-4">
|
||||
PHP, Tailwind CSS et le serveur fonctionnent correctement.
|
||||
</p>
|
||||
<div class="flex gap-4 justify-center">
|
||||
<span class="btn-primary">Bouton Primary</span>
|
||||
<span class="btn-secondary">Bouton Secondary</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Test responsive -->
|
||||
<p class="text-text-muted text-sm mt-12">
|
||||
Testé sur mobile, tablette et desktop.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php include_template('footer'); ?>
|
||||
```
|
||||
|
||||
### Configuration Nginx (Production)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name monportfolio.fr www.monportfolio.fr;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name monportfolio.fr www.monportfolio.fr;
|
||||
|
||||
# SSL
|
||||
ssl_certificate /etc/letsencrypt/live/monportfolio.fr/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/monportfolio.fr/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
root /var/www/portfolio;
|
||||
index index.php;
|
||||
charset utf-8;
|
||||
|
||||
# Headers de sécurité
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Bloquer fichiers sensibles
|
||||
location ~ /\.(env|git|htaccess) { deny all; return 404; }
|
||||
location ^~ /vendor/ { deny all; return 404; }
|
||||
location ^~ /node_modules/ { deny all; return 404; }
|
||||
location ^~ /logs/ { deny all; return 404; }
|
||||
location ^~ /data/ { deny all; return 404; }
|
||||
location ^~ /includes/ { deny all; return 404; }
|
||||
|
||||
# Assets statiques avec cache long
|
||||
location /assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
gzip_static on;
|
||||
}
|
||||
|
||||
# Router PHP (front controller)
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
# PHP-FPM
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
# Compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/javascript application/javascript application/json image/svg+xml;
|
||||
}
|
||||
```
|
||||
|
||||
### Fichiers à Déployer
|
||||
|
||||
**Inclure :**
|
||||
- `index.php`
|
||||
- `config.php`
|
||||
- `composer.json`, `composer.lock`
|
||||
- `vendor/` (après composer install --no-dev)
|
||||
- `pages/`
|
||||
- `templates/`
|
||||
- `includes/`
|
||||
- `api/`
|
||||
- `assets/` (avec output.css généré)
|
||||
- `data/`
|
||||
- `logs/` (dossier vide avec .gitkeep)
|
||||
- `.env` (créé sur le serveur, pas commité)
|
||||
|
||||
**Exclure :**
|
||||
- `node_modules/`
|
||||
- `package.json`, `package-lock.json`
|
||||
- `tailwind.config.js`, `postcss.config.js`
|
||||
- `.env` (local)
|
||||
- `.git/`
|
||||
- `docs/`
|
||||
|
||||
### Variables .env Production
|
||||
|
||||
```env
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://monportfolio.fr
|
||||
|
||||
RECAPTCHA_SITE_KEY=votre_cle_site
|
||||
RECAPTCHA_SECRET_KEY=votre_cle_secrete
|
||||
|
||||
CONTACT_EMAIL=contact@monportfolio.fr
|
||||
|
||||
APP_SECRET=une_cle_secrete_aleatoire_de_32_caracteres
|
||||
```
|
||||
|
||||
### Checklist Pré-Déploiement
|
||||
|
||||
- [ ] `npm run build` exécuté (CSS minifié)
|
||||
- [ ] `composer install --no-dev` exécuté
|
||||
- [ ] Fichier `.env` de production prêt
|
||||
- [ ] Configuration nginx testée localement
|
||||
- [ ] Certificat SSL valide
|
||||
|
||||
## Testing
|
||||
|
||||
### Tests Fonctionnels
|
||||
|
||||
- [ ] La page s'affiche correctement en production
|
||||
- [ ] Le titre "Portfolio en construction" est visible
|
||||
- [ ] La couleur d'accent (#FA784F) s'affiche
|
||||
- [ ] Les boutons sont stylés correctement
|
||||
- [ ] Pas d'erreur dans la console
|
||||
|
||||
### Tests Responsive
|
||||
|
||||
- [ ] Mobile (375px) : contenu lisible, pas de scroll horizontal
|
||||
- [ ] Tablette (768px) : mise en page correcte
|
||||
- [ ] Desktop (1280px) : centré avec max-width
|
||||
|
||||
### Tests Performance (Lighthouse)
|
||||
|
||||
| Métrique | Objectif | Maximum |
|
||||
|----------|----------|---------|
|
||||
| Performance | > 90 | > 80 |
|
||||
| Accessibility | > 90 | > 85 |
|
||||
| Best Practices | > 90 | > 85 |
|
||||
| SEO | > 90 | > 85 |
|
||||
| FCP | < 1.5s | < 2.5s |
|
||||
| LCP | < 2.5s | < 4s |
|
||||
|
||||
### Tests Sécurité
|
||||
|
||||
```bash
|
||||
# Tester les accès bloqués
|
||||
curl -I https://monportfolio.fr/.env # Doit retourner 404
|
||||
curl -I https://monportfolio.fr/vendor/ # Doit retourner 404
|
||||
curl -I https://monportfolio.fr/data/ # Doit retourner 404
|
||||
curl -I https://monportfolio.fr/includes/ # Doit retourner 404
|
||||
```
|
||||
|
||||
### Commandes de Déploiement
|
||||
|
||||
```bash
|
||||
# Sur le poste local
|
||||
npm run build
|
||||
composer install --no-dev
|
||||
|
||||
# Transfert (exemple rsync)
|
||||
rsync -avz --exclude='node_modules' --exclude='.git' --exclude='docs' \
|
||||
./ user@serveur:/var/www/portfolio/
|
||||
|
||||
# Sur le serveur
|
||||
sudo nginx -t # Tester la config nginx
|
||||
sudo systemctl reload nginx # Recharger nginx
|
||||
```
|
||||
|
||||
## Change Log
|
||||
|
||||
| Date | Version | Description | Author |
|
||||
|------|---------|-------------|--------|
|
||||
| 2026-01-22 | 0.1 | Création initiale de la story | Sarah (PO) |
|
||||
|
||||
## Dev Agent Record
|
||||
|
||||
### Agent Model Used
|
||||
|
||||
Claude Opus 4.5 (claude-opus-4-5-20251101)
|
||||
|
||||
### Debug Log References
|
||||
|
||||
_À compléter par le dev agent_
|
||||
|
||||
### Completion Notes List
|
||||
|
||||
- Page canary créée avec titre animé, badges, card de test, boutons
|
||||
- CSS regénéré (12 Ko minifié)
|
||||
- Dépendances PHP installées (vlucas/phpdotenv)
|
||||
- Configuration nginx exemple créée (nginx.conf.example)
|
||||
- Syntaxe PHP validée
|
||||
|
||||
**Tâches restantes (manuelles) :**
|
||||
- Créer .env de production sur le serveur
|
||||
- Copier nginx.conf.example et adapter pour votre serveur
|
||||
- Déployer les fichiers (rsync/FTP)
|
||||
- Configurer SSL/HTTPS
|
||||
- Tests de sécurité et performance
|
||||
|
||||
### File List
|
||||
|
||||
| Fichier | Action |
|
||||
|---------|--------|
|
||||
| `index.php` | Modifié |
|
||||
| `nginx.conf.example` | Créé |
|
||||
| `vendor/` | Installé |
|
||||
| `composer.lock` | Créé |
|
||||
| `assets/css/output.css` | Regénéré |
|
||||
|
||||
## QA Results
|
||||
|
||||
_À compléter par le QA agent_
|
||||
Reference in New Issue
Block a user