2026-03-16 01:48:48 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:48:48 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00
2026-03-16 01:47:07 +01:00

Slim Blog

PHP Slim PHPStan Tests Licence

Blog multi-utilisateurs modulaire développé avec Slim 4. Les domaines Auth, Category, Media, User et Shared sont indépendants du domaine métier et réutilisables sans modification pour d'autres projets (boutique, portfolio…).

Fonctionnalités

  • Articles — création, édition, suppression avec éditeur WYSIWYG, slugs stables
  • Catégories — filtrage sur la page d'accueil et dans l'interface admin
  • Médias — upload WebP avec déduplication SHA-256
  • Recherche — full-text FTS5 cumulable avec le filtre catégorie
  • Comptes — trois rôles (user, editor, admin), réinitialisation de mot de passe par email
  • RSS — flux 2.0 des 20 derniers articles (/rss.xml)
  • Protection brute-force — verrouillage par IP après trop de tentatives échouées sur la connexion et la réinitialisation de mot de passe

Stack

Rôle Librairie
Framework HTTP Slim 4
Base de données SQLite via PDO natif
Templates Twig
CSS Sass (7-1, BEM)
Éditeur WYSIWYG Trumbowyg
Emails PHPMailer
Logging Monolog
Sanitisation HTML HTMLPurifier
Protection CSRF Slim CSRF
Injection de dépendances PHP-DI (autowiring)
Analyse statique PHPStan (niveau 8)

Développement

Prérequis : PHP 8.1+ avec pdo_sqlite, intl, fileinfo, gd (WebP), xml (dom), Composer, Node.js 18+

git clone https://git.netig.net/netig/slim-blog
cd slim-blog
composer install
npm install && npm run build
cp .env.example .env
php -S localhost:8080 -t public

Pour surveiller les modifications SCSS et recompiler automatiquement en développement :

npm run watch

npm run watch est réservé au développement local. En production, le CSS est compilé une fois lors du build Docker.

Pour tester l'upload de fichiers, augmenter les limites PHP :

php -S localhost:8080 -t public -d upload_max_filesize=6M -d post_max_size=8M

Si upload_max_filesize est trop basse, PHP abandonne l'intégralité du corps POST — fichier et tokens CSRF — ce qui provoque une erreur générique sans message explicite.

Production

Prérequis : Docker, Docker Compose

git clone https://git.netig.net/netig/slim-blog
cd slim-blog
cp .env.example .env
# Définir APP_ENV=production, APP_URL, ADMIN_PASSWORD et la configuration SMTP
docker compose up -d --build

Le démarrage en production avec ADMIN_PASSWORD=changeme123 est bloqué intentionnellement.

--build est superflu sur une machine vierge mais garantit une image à jour dans tous les cas.

Note sur le .env : docker-compose.yml monte le fichier .env physiquement dans le conteneur (- ./.env:/var/www/app/.env:ro). Ce mount est nécessaire car phpdotenv lit un fichier sur le disque via file_get_contentsenv_file seul ne suffit pas.

Au premier démarrage, l'entrypoint initialise automatiquement ./data/ sur l'hôte :

data/
├── public/       # assets compilés, index.php — servis par Nginx
│   └── media/    # uploads utilisateurs — persistés entre redéploiements
├── database/     # migrations + app.sqlite
└── var/          # cache Twig/HTMLPurifier, logs

Pour mettre à jour le site après un changement de code :

docker compose build
docker compose up -d

Logs Docker

Les erreurs PHP remontent dans docker compose logs grâce à error_log = /dev/stderr dans docker/php/php.ini. Sans ce réglage, les erreurs des workers FPM ne sont pas transmises au process principal et n'apparaissent pas dans les logs Docker.

Durcissement HTTP

docker/php/php.ini désactive l'en-tête X-Powered-By (expose_php = Off) et renomme le cookie de session de PHPSESSID en sid pour ne pas exposer la stack technique.

docker/nginx/default.conf ajoute quatre en-têtes de sécurité sur toutes les réponses :

En-tête Valeur Protection
X-Frame-Options SAMEORIGIN Clickjacking
X-Content-Type-Options nosniff Sniffing MIME
Referrer-Policy strict-origin-when-cross-origin Fuite d'URL
Permissions-Policy camera=(), microphone=(), geolocation=() APIs navigateur

Derrière un reverse proxy (Caddy, Nginx…)

Nginx écoute sur 127.0.0.1:8888 (câblé dans docker-compose.yml).

Exemple de configuration Caddy :

https://blog.exemple.com {
    header Strict-Transport-Security max-age=31536000;
    reverse_proxy localhost:8888
}

Variables d'environnement

Variable Description Exemple
APP_ENV development ou production production
APP_URL URL de base (liens emails, flux RSS) — inclure le port en développement http://localhost:8080
APP_NAME Nom du blog (flux RSS, emails) Slim Blog
TIMEZONE Fuseau horaire PHP Europe/Paris
ADMIN_USERNAME Nom d'utilisateur du compte admin admin
ADMIN_EMAIL Email du compte admin admin@example.com
ADMIN_PASSWORD Mot de passe admin (obligatoire en production) (à changer)
MAIL_HOST Serveur SMTP smtp.example.com
MAIL_PORT Port SMTP (587 TLS, 465 SSL) 587
MAIL_USERNAME Identifiant SMTP noreply@example.com
MAIL_PASSWORD Mot de passe SMTP (à renseigner)
MAIL_ENCRYPTION tls ou ssl tls
MAIL_FROM Adresse expéditeur noreply@example.com
MAIL_FROM_NAME Nom expéditeur Slim Blog
UPLOAD_MAX_SIZE Taille max upload en octets 5242880

Documentation

Licence

Le code source est distribué sous licence MIT. Le contenu du blog (articles publiés) est soumis à CC BY-SA 4.0.

Provisioning

Le provisionnement (migrations + seed admin) peut etre execute explicitement via php bin/provision.php. En developpement, il reste activable automatiquement via APP_AUTO_PROVISION=true. En production, il est recommande de le lancer separement du runtime HTTP.

Description
No description provided
Readme MIT 640 KiB
Languages
PHP 87.7%
Twig 6.9%
SCSS 4.8%
Shell 0.3%
Dockerfile 0.3%