4.5 KiB
F3 Simple Blog
Blog simple avec Fat-Free Framework.
Structure
project/
├── config.local.ini # Surcharges locales (gitignored)
├── app/
│ ├── config.ini # Routes et variables F3
│ ├── bootstrap.php # Initialisation (DB, session, cache, erreurs)
│ ├── Controllers/
│ ├── Helpers/ # Fonctions utilitaires (App.php, Error.php)
│ ├── Models/ # DB\SQL\Mapper (Post, Media, User)
│ ├── Services/ # MarkdownService
│ └── Views/
├── db/
│ └── app.sqlite
├── logs/
│ ├── app.log
│ └── php-error.log
├── public/
│ ├── assets/ # Sources CSS/JS (servis minifiés via /min/@file)
│ └── uploads/
│ └── media/ # Images converties en PNG (sans perte)
└── tmp/
├── cache/ # Cache F3 (pages publiques + assets minifiés)
└── uploads/ # Transit Web::receive() — vidé après chaque upload
Philosophie des dossiers runtime
Le projet garde la même logique en local et dans Docker :
tmp/= runtime temporaire, recréabledb/= base SQLite persistantelogs/= logs persistantspublic/uploads/media/= médias publiés et persistants
Autrement dit, tmp/ peut être vidé sans perte métier. Les données à sauvegarder restent hors de tmp/.
Fonctionnalités F3 utilisées
- Routage nommé —
config.ini [routes],$f3->alias() - Cache HTTP + serveur —
$f3->expire()sur les routes publiques,Cache::reset('.url')à la mutation - Assets minifiés —
Web::minify()viaAssetController(GET /min/@file) - Upload —
Web::receive()avec callback de validation taille - Images —
Image(chargement, conversion PNG, dimensions),Base::write()pour l'écriture - Markdown —
Markdown::instance()->convert() - Slugs —
Web::instance()->slug() - Session —
$f3->set('JAR', …), token CSRF dansSESSION.csrf_token - Logging —
Logde F3 avec fallbackfile_put_contents - ORM —
DB\SQL\Mapper:paginate(),copyfrom(),cast(),find()
Prérequis
Développement local
- PHP 8.3+
- Composer
- Extensions PHP :
pdo_sqlite,dom,gd,mbstring
Déploiement Docker
- Docker
- Docker Compose
Configuration
Les paramètres par défaut sont dans app/config.ini.
Pour surcharger localement ou en production :
cp config.local.ini.example config.local.ini
Réglages minimums conseillés en production :
[globals]
app.env=prod
app.timezone=Europe/Paris
Le fichier config.local.ini sert uniquement aux surcharges d'environnement. Les chemins runtime restent les mêmes partout :
tmp/cache/pour le cache F3 et les assets minifiéstmp/uploads/pour les fichiers temporaires d'upload
Développement local
composer install
cp config.local.ini.example config.local.ini
php scripts/install.php
php -S 127.0.0.1:8080 -t public
Ouvre ensuite http://127.0.0.1:8080.
Créer un compte admin :
php scripts/create-admin.php admin
# mot de passe : 10 caractères minimum
Déploiement avec Docker
cp config.local.ini.example config.local.ini
# édite config.local.ini (app.env=prod, app.timezone, etc.)
docker compose up -d --build
Docker monte les mêmes dossiers runtime que le développement local. Seuls les répertoires persistants restent séparés de tmp/.
Si config.local.ini n'existe pas, le conteneur démarre avec les valeurs par défaut de app/config.ini.
Le service écoute sur http://127.0.0.1:8888.
Créer un compte admin :
docker compose exec app php scripts/create-admin.php admin
# mot de passe : 10 caractères minimum
Reverse proxy Caddy
Caddy sur le même hôte
blog.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:8888
}
Caddy dans Docker
Si Caddy tourne aussi dans Docker, place-le sur le même réseau que app et cible directement le service :
blog.example.com {
encode zstd gzip
reverse_proxy app:80
}
Données à sauvegarder
db/— base SQLitepublic/uploads/media/— imageslogs/— optionneltmp/— non persistant, recréable
Mise à jour
docker compose up -d --build
Logs
- Applicatifs :
logs/app.log - PHP :
logs/php-error.log - Apache (conteneur) :
docker compose logs -f app