From 6359003522a335dfd3f7df1e3a7e444aa1313cc7 Mon Sep 17 00:00:00 2001 From: Franck DAKIA Date: Mon, 9 Mar 2026 11:32:00 +0000 Subject: [PATCH] Update install and scheduler --- docs/installation.mdx | 266 +++++++++++++++++--- docs/scheduler.mdx | 243 +++++++++--------- versioned_docs/version-5.x/installation.mdx | 266 +++++++++++++++++--- versioned_docs/version-5.x/scheduler.mdx | 243 +++++++++--------- 4 files changed, 728 insertions(+), 290 deletions(-) diff --git a/docs/installation.mdx b/docs/installation.mdx index ade2928..359e5c0 100644 --- a/docs/installation.mdx +++ b/docs/installation.mdx @@ -40,7 +40,7 @@ Si vous découvrez Composer, prenez le temps de parcourir sa [documentation](htt [![asciicast](https://asciinema.org/a/s8HpeoaUwnxEZ7OOPRxxXE52z.svg)](https://asciinema.org/a/s8HpeoaUwnxEZ7OOPRxxXE52z) -## 🚀 Démarrer votre projet +## Démarrer votre projet Rendez-vous à la racine de votre projet et démarrez le serveur de développement : @@ -60,7 +60,7 @@ php bow run:server ``` ::: -## ⚙️ Configuration +## Configuration ### Dossier public @@ -119,33 +119,237 @@ RewriteRule ^ index.php [L] ### Nginx -Pour Nginx, ajoutez cette configuration dans votre bloc `server` : +Pour Nginx, ajoutez cette configuration dans votre fichier de site : -```nginx +```nginx title="/etc/nginx/sites-available/bow-app" server { - listen 80; - server_name example.com; - root /path/to/your/project/public; - - index index.php index.html; - - location / { - try_files $uri $uri/ /index.php?$query_string; - } - - location ~ \.php$ { - fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - include fastcgi_params; - } - - location ~ /\.(?!well-known).* { - deny all; - } + listen 80; + server_name example.com www.example.com; + root /var/www/bow-app/public; + index index.php; + + # Logs + access_log /var/log/nginx/bow-app.access.log; + error_log /var/log/nginx/bow-app.error.log; + + # Sécurité - Headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript + application/javascript application/json application/xml; + + # Front Controller + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # PHP-FPM + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_hide_header X-Powered-By; + } + + # Cache des assets statiques + location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + access_log off; + } + + # Bloquer l'accès aux fichiers sensibles + location ~ /\.(env|git|htaccess) { + deny all; + } + + location ~ ^/(var|vendor|config|migrations|seeders)/ { + deny all; + } } ``` +#### Nginx avec SSL (HTTPS) + +```nginx title="/etc/nginx/sites-available/bow-app-ssl" +server { + listen 80; + server_name example.com www.example.com; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name example.com www.example.com; + root /var/www/bow-app/public; + index index.php; + + # Certificats SSL (Let's Encrypt) + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + # Configuration SSL moderne + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; + ssl_prefer_server_ciphers off; + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + ssl_stapling on; + ssl_stapling_verify on; + + # Headers de sécurité + add_header Strict-Transport-Security "max-age=63072000" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(env|git|htaccess) { + deny all; + } +} +``` + +#### Activer le site Nginx + +```bash +# Créer le lien symbolique +sudo ln -s /etc/nginx/sites-available/bow-app /etc/nginx/sites-enabled/ + +# Tester la configuration +sudo nginx -t + +# Recharger Nginx +sudo systemctl reload nginx +``` + +### Docker + +Pour développer avec Docker, créez les fichiers suivants à la racine du projet : + +```dockerfile title="Dockerfile" +FROM php:8.2-fpm-alpine + +# Extensions PHP +RUN apk add --no-cache \ + libpng-dev libjpeg-turbo-dev freetype-dev \ + oniguruma-dev libxml2-dev zip unzip git curl \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install pdo pdo_mysql mbstring xml gd opcache + +# Composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +WORKDIR /var/www/html + +COPY . . + +RUN composer install --no-dev --optimize-autoloader \ + && chown -R www-data:www-data var/ + +EXPOSE 9000 + +CMD ["php-fpm"] +``` + +```yaml title="docker-compose.yml" +services: + app: + build: . + volumes: + - .:/var/www/html + - ./var:/var/www/html/var + depends_on: + - mysql + - redis + networks: + - bow-network + + nginx: + image: nginx:alpine + ports: + - "8080:80" + volumes: + - .:/var/www/html + - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + depends_on: + - app + networks: + - bow-network + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: secret + MYSQL_DATABASE: bow_app + MYSQL_USER: bow + MYSQL_PASSWORD: secret + volumes: + - mysql-data:/var/lib/mysql + ports: + - "3306:3306" + networks: + - bow-network + + redis: + image: redis:alpine + ports: + - "6379:6379" + networks: + - bow-network + +networks: + bow-network: + driver: bridge + +volumes: + mysql-data: +``` + +```nginx title="docker/nginx.conf" +server { + listen 80; + root /var/www/html/public; + index index.php; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } +} +``` + +```bash +# Démarrer les conteneurs +docker-compose up -d + +# Accéder à l'application +# http://localhost:8080 +``` + ### Déploiement sur serveur mutualisé Pour déployer Bow Framework sur un hébergement mutualisé : @@ -177,18 +381,18 @@ Options -indexes ``` :::tip Gestion des assets -Pour un hébergement mutualisé, utilisez le helper `app_assets()` pour vos fichiers statiques et modifiez la valeur de `APP_ASSET_PREFIX` à `/public` dans votre fichier `.env.json`. Bow gérera automatiquement les chemins corrects ! 🚀 +Pour un hébergement mutualisé, utilisez le helper `app_assets()` pour vos fichiers statiques et modifiez la valeur de `APP_ASSET_PREFIX` à `/public` dans votre fichier `.env.json`. Bow gérera automatiquement les chemins corrects ! ::: ## Prochaines étapes Maintenant que votre installation est terminée, découvrez comment construire votre application : -- 🛣️ [Créer vos premières routes](./routing) -- 🎮 [Utiliser les contrôleurs](./controller) -- 💾 [Travailler avec les bases de données](./database) -- 🔐 [Gérer les sessions utilisateur](./session) -- 📦 [Utiliser le système de stockage](./storage) -- 🎨 [Créer des vues avec Tintin](./views) +- [Créer vos premières routes](./routing) +- [Utiliser les contrôleurs](./controller) +- [Travailler avec les bases de données](./database) +- [Gérer les sessions utilisateur](./session) +- [Utiliser le système de stockage](./storage) +- [Créer des vues avec Tintin](./views) diff --git a/docs/scheduler.mdx b/docs/scheduler.mdx index f140319..a6ba318 100644 --- a/docs/scheduler.mdx +++ b/docs/scheduler.mdx @@ -38,43 +38,43 @@ use Bow\Configuration\Loader as ApplicationLoader; class Kernel extends ApplicationLoader { - /** - * Define your scheduled tasks - * - * @param Scheduler $schedule - * @return void - */ - public function schedules(Scheduler $schedule): void - { - // Planifier une commande console Bow - $schedule->command('cache:clear') - ->daily() - ->at('02:00') - ->description('Nettoyer le cache de l\'application'); - - // Planifier une commande shell - $schedule->exec('mysqldump -u root mydb > /backups/db.sql') - ->daily() - ->at('03:00') - ->description('Sauvegarder la base de données') - ->runInBackground(); - - // Planifier une closure - $schedule->call(function () { - logger('Tâche de nettoyage exécutée...'); - }) - ->hourly() - ->description('Tâche de nettoyage'); - - // Planifier un QueueTask - $schedule->task(App\Tasks\SendWeeklyReportTask::class) - ->weekly() - ->sundays() - ->at('10:00') - ->description('Envoyer les rapports hebdomadaires'); - } + /** + * Define your scheduled tasks + * + * @param Scheduler $schedule + * @return void + */ + public function schedules(Scheduler $schedule): void + { + // Planifier une commande console Bow + $schedule->command('cache:clear') + ->daily() + ->at('02:00') + ->description('Nettoyer le cache de l\'application'); - // ... autres méthodes du Kernel + // Planifier une commande shell + $schedule->exec('mysqldump -u root mydb > /backups/db.sql') + ->daily() + ->at('03:00') + ->description('Sauvegarder la base de données') + ->runInBackground(); + + // Planifier une closure + $schedule->call(function () { + logger('Tâche de nettoyage exécutée...'); + }) + ->hourly() + ->description('Tâche de nettoyage'); + + // Planifier un QueueTask + $schedule->task(App\Tasks\SendWeeklyReportTask::class) + ->weekly() + ->sundays() + ->at('10:00') + ->description('Envoyer les rapports hebdomadaires'); + } + + // ... autres méthodes du Kernel } ``` @@ -305,17 +305,17 @@ Exécutez des tâches uniquement lorsque certaines conditions sont remplies : ```php // Exécuter seulement si la condition est vraie $schedule->command('send:emails') - ->daily() - ->when(function () { - return app()->environment('production'); - }); + ->daily() + ->when(function () { + return app()->environment('production'); + }); // Sauter si la condition est vraie $schedule->command('debug:task') - ->daily() - ->skip(function () { - return app()->environment('production'); - }); + ->daily() + ->skip(function () { + return app()->environment('production'); + }); ``` ### Fuseau horaire @@ -383,48 +383,63 @@ php bow schedule:test 0 ## Configuration en production -### Avec cron +### Cron -En production, ajoutez une entrée cron qui exécute le planificateur chaque minute : +Ajoutez cette entrée cron pour exécuter le planificateur chaque minute : ```bash -* * * * * cd /path-to-your-project && php bow schedule:run >> /dev/null 2>&1 +* * * * * cd /var/www/bow-app && php bow schedule:run >> /var/log/bow-scheduler.log 2>&1 ``` -:::tip Conseil -Cette unique entrée cron permet au planificateur de gérer toutes vos tâches planifiées. -::: - -### Avec le mode démon +### Supervisor -Utilisez le mode démon pour une meilleure performance : +```ini title="/etc/supervisor/conf.d/bow-scheduler.conf" +[program:bow-scheduler] +directory=/var/www/bow-app +command=php bow schedule:work +autostart=true +autorestart=true +user=www-data +stdout_logfile=/var/log/bow-scheduler.log +``` ```bash -php bow schedule:work +sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl start bow-scheduler ``` -### Avec Supervisor +### systemd -Pour le mode démon, utilisez un gestionnaire de processus comme Supervisor : +```ini title="/etc/systemd/system/bow-scheduler.service" +[Unit] +Description=Bow Scheduler +After=network.target -```ini title="/etc/supervisor/conf.d/scheduler.conf" -[program:scheduler] -process_name=%(program_name)s -directory=/var/www/your-app -command=php bow schedule:work -autostart=true -autorestart=true -user=www-data -redirect_stderr=true -stdout_logfile=/var/log/scheduler.log -``` +[Service] +User=www-data +WorkingDirectory=/var/www/bow-app +ExecStart=/usr/bin/php bow schedule:work +Restart=always -Ensuite, rechargez Supervisor : +[Install] +WantedBy=multi-user.target +``` ```bash -sudo supervisorctl reread -sudo supervisorctl update -sudo supervisorctl start scheduler +sudo systemctl daemon-reload && sudo systemctl enable bow-scheduler && sudo systemctl start bow-scheduler +``` + +### Docker + +```yaml title="docker-compose.yml" +services: + scheduler: + build: . + command: php bow schedule:work + restart: unless-stopped + volumes: + - .:/var/www/html + depends_on: + - mysql ``` ## Exemple complet @@ -441,51 +456,51 @@ use Bow\Configuration\Loader as ApplicationLoader; class Kernel extends ApplicationLoader { - public function schedules(Scheduler $schedule): void - { - // Sauvegarde quotidienne de la base de données - $schedule->exec('mysqldump mydb > /backups/daily.sql') - ->daily() - ->at('01:00') - ->description('Sauvegarde quotidienne de la base de données') - ->runInBackground(); - - // Vider le cache chaque dimanche - $schedule->command('cache:clear') - ->weekly() - ->sundays() - ->at('02:00') - ->description('Nettoyage hebdomadaire du cache'); - - // Traiter les rapports en attente chaque heure - $schedule->task(\App\Tasks\ProcessPendingReportsTask::class) - ->hourly() - ->withoutOverlapping() - ->description('Traiter les rapports en attente'); - - // Vérifier l'état du système toutes les 5 minutes - $schedule->call(function () { - $health = \App\Services\HealthChecker::check(); - if (!$health->isHealthy()) { - \App\Services\AlertService::notify($health); - } - }) - ->everyFiveMinutes() - ->description('Vérification de l\'état du système'); - - // Envoyer les rapports hebdomadaires (seulement en production) - $schedule->task(\App\Tasks\SendWeeklyReportTask::class) - ->weekly() - ->fridays() - ->at('17:00') - ->timezone('Europe/Paris') - ->when(function () { - return app()->environment('production'); - }) - ->description('Envoi des rapports hebdomadaires'); + public function schedules(Scheduler $schedule): void + { + // Sauvegarde quotidienne de la base de données + $schedule->exec('mysqldump mydb > /backups/daily.sql') + ->daily() + ->at('01:00') + ->description('Sauvegarde quotidienne de la base de données') + ->runInBackground(); + + // Vider le cache chaque dimanche + $schedule->command('cache:clear') + ->weekly() + ->sundays() + ->at('02:00') + ->description('Nettoyage hebdomadaire du cache'); + + // Traiter les rapports en attente chaque heure + $schedule->task(\App\Tasks\ProcessPendingReportsTask::class) + ->hourly() + ->withoutOverlapping() + ->description('Traiter les rapports en attente'); + + // Vérifier l'état du système toutes les 5 minutes + $schedule->call(function () { + $health = \App\Services\HealthChecker::check(); + if (!$health->isHealthy()) { + \App\Services\AlertService::notify($health); } + }) + ->everyFiveMinutes() + ->description('Vérification de l\'état du système'); + + // Envoyer les rapports hebdomadaires (seulement en production) + $schedule->task(\App\Tasks\SendWeeklyReportTask::class) + ->weekly() + ->fridays() + ->at('17:00') + ->timezone('Europe/Paris') + ->when(function () { + return app()->environment('production'); + }) + ->description('Envoi des rapports hebdomadaires'); + } - // ... autres méthodes + // ... autres méthodes } ``` diff --git a/versioned_docs/version-5.x/installation.mdx b/versioned_docs/version-5.x/installation.mdx index ade2928..359e5c0 100644 --- a/versioned_docs/version-5.x/installation.mdx +++ b/versioned_docs/version-5.x/installation.mdx @@ -40,7 +40,7 @@ Si vous découvrez Composer, prenez le temps de parcourir sa [documentation](htt [![asciicast](https://asciinema.org/a/s8HpeoaUwnxEZ7OOPRxxXE52z.svg)](https://asciinema.org/a/s8HpeoaUwnxEZ7OOPRxxXE52z) -## 🚀 Démarrer votre projet +## Démarrer votre projet Rendez-vous à la racine de votre projet et démarrez le serveur de développement : @@ -60,7 +60,7 @@ php bow run:server ``` ::: -## ⚙️ Configuration +## Configuration ### Dossier public @@ -119,33 +119,237 @@ RewriteRule ^ index.php [L] ### Nginx -Pour Nginx, ajoutez cette configuration dans votre bloc `server` : +Pour Nginx, ajoutez cette configuration dans votre fichier de site : -```nginx +```nginx title="/etc/nginx/sites-available/bow-app" server { - listen 80; - server_name example.com; - root /path/to/your/project/public; - - index index.php index.html; - - location / { - try_files $uri $uri/ /index.php?$query_string; - } - - location ~ \.php$ { - fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - include fastcgi_params; - } - - location ~ /\.(?!well-known).* { - deny all; - } + listen 80; + server_name example.com www.example.com; + root /var/www/bow-app/public; + index index.php; + + # Logs + access_log /var/log/nginx/bow-app.access.log; + error_log /var/log/nginx/bow-app.error.log; + + # Sécurité - Headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript + application/javascript application/json application/xml; + + # Front Controller + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # PHP-FPM + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_hide_header X-Powered-By; + } + + # Cache des assets statiques + location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + access_log off; + } + + # Bloquer l'accès aux fichiers sensibles + location ~ /\.(env|git|htaccess) { + deny all; + } + + location ~ ^/(var|vendor|config|migrations|seeders)/ { + deny all; + } } ``` +#### Nginx avec SSL (HTTPS) + +```nginx title="/etc/nginx/sites-available/bow-app-ssl" +server { + listen 80; + server_name example.com www.example.com; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name example.com www.example.com; + root /var/www/bow-app/public; + index index.php; + + # Certificats SSL (Let's Encrypt) + ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; + + # Configuration SSL moderne + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; + ssl_prefer_server_ciphers off; + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + ssl_stapling on; + ssl_stapling_verify on; + + # Headers de sécurité + add_header Strict-Transport-Security "max-age=63072000" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(env|git|htaccess) { + deny all; + } +} +``` + +#### Activer le site Nginx + +```bash +# Créer le lien symbolique +sudo ln -s /etc/nginx/sites-available/bow-app /etc/nginx/sites-enabled/ + +# Tester la configuration +sudo nginx -t + +# Recharger Nginx +sudo systemctl reload nginx +``` + +### Docker + +Pour développer avec Docker, créez les fichiers suivants à la racine du projet : + +```dockerfile title="Dockerfile" +FROM php:8.2-fpm-alpine + +# Extensions PHP +RUN apk add --no-cache \ + libpng-dev libjpeg-turbo-dev freetype-dev \ + oniguruma-dev libxml2-dev zip unzip git curl \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install pdo pdo_mysql mbstring xml gd opcache + +# Composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +WORKDIR /var/www/html + +COPY . . + +RUN composer install --no-dev --optimize-autoloader \ + && chown -R www-data:www-data var/ + +EXPOSE 9000 + +CMD ["php-fpm"] +``` + +```yaml title="docker-compose.yml" +services: + app: + build: . + volumes: + - .:/var/www/html + - ./var:/var/www/html/var + depends_on: + - mysql + - redis + networks: + - bow-network + + nginx: + image: nginx:alpine + ports: + - "8080:80" + volumes: + - .:/var/www/html + - ./docker/nginx.conf:/etc/nginx/conf.d/default.conf + depends_on: + - app + networks: + - bow-network + + mysql: + image: mysql:8.0 + environment: + MYSQL_ROOT_PASSWORD: secret + MYSQL_DATABASE: bow_app + MYSQL_USER: bow + MYSQL_PASSWORD: secret + volumes: + - mysql-data:/var/lib/mysql + ports: + - "3306:3306" + networks: + - bow-network + + redis: + image: redis:alpine + ports: + - "6379:6379" + networks: + - bow-network + +networks: + bow-network: + driver: bridge + +volumes: + mysql-data: +``` + +```nginx title="docker/nginx.conf" +server { + listen 80; + root /var/www/html/public; + index index.php; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + } +} +``` + +```bash +# Démarrer les conteneurs +docker-compose up -d + +# Accéder à l'application +# http://localhost:8080 +``` + ### Déploiement sur serveur mutualisé Pour déployer Bow Framework sur un hébergement mutualisé : @@ -177,18 +381,18 @@ Options -indexes ``` :::tip Gestion des assets -Pour un hébergement mutualisé, utilisez le helper `app_assets()` pour vos fichiers statiques et modifiez la valeur de `APP_ASSET_PREFIX` à `/public` dans votre fichier `.env.json`. Bow gérera automatiquement les chemins corrects ! 🚀 +Pour un hébergement mutualisé, utilisez le helper `app_assets()` pour vos fichiers statiques et modifiez la valeur de `APP_ASSET_PREFIX` à `/public` dans votre fichier `.env.json`. Bow gérera automatiquement les chemins corrects ! ::: ## Prochaines étapes Maintenant que votre installation est terminée, découvrez comment construire votre application : -- 🛣️ [Créer vos premières routes](./routing) -- 🎮 [Utiliser les contrôleurs](./controller) -- 💾 [Travailler avec les bases de données](./database) -- 🔐 [Gérer les sessions utilisateur](./session) -- 📦 [Utiliser le système de stockage](./storage) -- 🎨 [Créer des vues avec Tintin](./views) +- [Créer vos premières routes](./routing) +- [Utiliser les contrôleurs](./controller) +- [Travailler avec les bases de données](./database) +- [Gérer les sessions utilisateur](./session) +- [Utiliser le système de stockage](./storage) +- [Créer des vues avec Tintin](./views) diff --git a/versioned_docs/version-5.x/scheduler.mdx b/versioned_docs/version-5.x/scheduler.mdx index f140319..a6ba318 100644 --- a/versioned_docs/version-5.x/scheduler.mdx +++ b/versioned_docs/version-5.x/scheduler.mdx @@ -38,43 +38,43 @@ use Bow\Configuration\Loader as ApplicationLoader; class Kernel extends ApplicationLoader { - /** - * Define your scheduled tasks - * - * @param Scheduler $schedule - * @return void - */ - public function schedules(Scheduler $schedule): void - { - // Planifier une commande console Bow - $schedule->command('cache:clear') - ->daily() - ->at('02:00') - ->description('Nettoyer le cache de l\'application'); - - // Planifier une commande shell - $schedule->exec('mysqldump -u root mydb > /backups/db.sql') - ->daily() - ->at('03:00') - ->description('Sauvegarder la base de données') - ->runInBackground(); - - // Planifier une closure - $schedule->call(function () { - logger('Tâche de nettoyage exécutée...'); - }) - ->hourly() - ->description('Tâche de nettoyage'); - - // Planifier un QueueTask - $schedule->task(App\Tasks\SendWeeklyReportTask::class) - ->weekly() - ->sundays() - ->at('10:00') - ->description('Envoyer les rapports hebdomadaires'); - } + /** + * Define your scheduled tasks + * + * @param Scheduler $schedule + * @return void + */ + public function schedules(Scheduler $schedule): void + { + // Planifier une commande console Bow + $schedule->command('cache:clear') + ->daily() + ->at('02:00') + ->description('Nettoyer le cache de l\'application'); - // ... autres méthodes du Kernel + // Planifier une commande shell + $schedule->exec('mysqldump -u root mydb > /backups/db.sql') + ->daily() + ->at('03:00') + ->description('Sauvegarder la base de données') + ->runInBackground(); + + // Planifier une closure + $schedule->call(function () { + logger('Tâche de nettoyage exécutée...'); + }) + ->hourly() + ->description('Tâche de nettoyage'); + + // Planifier un QueueTask + $schedule->task(App\Tasks\SendWeeklyReportTask::class) + ->weekly() + ->sundays() + ->at('10:00') + ->description('Envoyer les rapports hebdomadaires'); + } + + // ... autres méthodes du Kernel } ``` @@ -305,17 +305,17 @@ Exécutez des tâches uniquement lorsque certaines conditions sont remplies : ```php // Exécuter seulement si la condition est vraie $schedule->command('send:emails') - ->daily() - ->when(function () { - return app()->environment('production'); - }); + ->daily() + ->when(function () { + return app()->environment('production'); + }); // Sauter si la condition est vraie $schedule->command('debug:task') - ->daily() - ->skip(function () { - return app()->environment('production'); - }); + ->daily() + ->skip(function () { + return app()->environment('production'); + }); ``` ### Fuseau horaire @@ -383,48 +383,63 @@ php bow schedule:test 0 ## Configuration en production -### Avec cron +### Cron -En production, ajoutez une entrée cron qui exécute le planificateur chaque minute : +Ajoutez cette entrée cron pour exécuter le planificateur chaque minute : ```bash -* * * * * cd /path-to-your-project && php bow schedule:run >> /dev/null 2>&1 +* * * * * cd /var/www/bow-app && php bow schedule:run >> /var/log/bow-scheduler.log 2>&1 ``` -:::tip Conseil -Cette unique entrée cron permet au planificateur de gérer toutes vos tâches planifiées. -::: - -### Avec le mode démon +### Supervisor -Utilisez le mode démon pour une meilleure performance : +```ini title="/etc/supervisor/conf.d/bow-scheduler.conf" +[program:bow-scheduler] +directory=/var/www/bow-app +command=php bow schedule:work +autostart=true +autorestart=true +user=www-data +stdout_logfile=/var/log/bow-scheduler.log +``` ```bash -php bow schedule:work +sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl start bow-scheduler ``` -### Avec Supervisor +### systemd -Pour le mode démon, utilisez un gestionnaire de processus comme Supervisor : +```ini title="/etc/systemd/system/bow-scheduler.service" +[Unit] +Description=Bow Scheduler +After=network.target -```ini title="/etc/supervisor/conf.d/scheduler.conf" -[program:scheduler] -process_name=%(program_name)s -directory=/var/www/your-app -command=php bow schedule:work -autostart=true -autorestart=true -user=www-data -redirect_stderr=true -stdout_logfile=/var/log/scheduler.log -``` +[Service] +User=www-data +WorkingDirectory=/var/www/bow-app +ExecStart=/usr/bin/php bow schedule:work +Restart=always -Ensuite, rechargez Supervisor : +[Install] +WantedBy=multi-user.target +``` ```bash -sudo supervisorctl reread -sudo supervisorctl update -sudo supervisorctl start scheduler +sudo systemctl daemon-reload && sudo systemctl enable bow-scheduler && sudo systemctl start bow-scheduler +``` + +### Docker + +```yaml title="docker-compose.yml" +services: + scheduler: + build: . + command: php bow schedule:work + restart: unless-stopped + volumes: + - .:/var/www/html + depends_on: + - mysql ``` ## Exemple complet @@ -441,51 +456,51 @@ use Bow\Configuration\Loader as ApplicationLoader; class Kernel extends ApplicationLoader { - public function schedules(Scheduler $schedule): void - { - // Sauvegarde quotidienne de la base de données - $schedule->exec('mysqldump mydb > /backups/daily.sql') - ->daily() - ->at('01:00') - ->description('Sauvegarde quotidienne de la base de données') - ->runInBackground(); - - // Vider le cache chaque dimanche - $schedule->command('cache:clear') - ->weekly() - ->sundays() - ->at('02:00') - ->description('Nettoyage hebdomadaire du cache'); - - // Traiter les rapports en attente chaque heure - $schedule->task(\App\Tasks\ProcessPendingReportsTask::class) - ->hourly() - ->withoutOverlapping() - ->description('Traiter les rapports en attente'); - - // Vérifier l'état du système toutes les 5 minutes - $schedule->call(function () { - $health = \App\Services\HealthChecker::check(); - if (!$health->isHealthy()) { - \App\Services\AlertService::notify($health); - } - }) - ->everyFiveMinutes() - ->description('Vérification de l\'état du système'); - - // Envoyer les rapports hebdomadaires (seulement en production) - $schedule->task(\App\Tasks\SendWeeklyReportTask::class) - ->weekly() - ->fridays() - ->at('17:00') - ->timezone('Europe/Paris') - ->when(function () { - return app()->environment('production'); - }) - ->description('Envoi des rapports hebdomadaires'); + public function schedules(Scheduler $schedule): void + { + // Sauvegarde quotidienne de la base de données + $schedule->exec('mysqldump mydb > /backups/daily.sql') + ->daily() + ->at('01:00') + ->description('Sauvegarde quotidienne de la base de données') + ->runInBackground(); + + // Vider le cache chaque dimanche + $schedule->command('cache:clear') + ->weekly() + ->sundays() + ->at('02:00') + ->description('Nettoyage hebdomadaire du cache'); + + // Traiter les rapports en attente chaque heure + $schedule->task(\App\Tasks\ProcessPendingReportsTask::class) + ->hourly() + ->withoutOverlapping() + ->description('Traiter les rapports en attente'); + + // Vérifier l'état du système toutes les 5 minutes + $schedule->call(function () { + $health = \App\Services\HealthChecker::check(); + if (!$health->isHealthy()) { + \App\Services\AlertService::notify($health); } + }) + ->everyFiveMinutes() + ->description('Vérification de l\'état du système'); + + // Envoyer les rapports hebdomadaires (seulement en production) + $schedule->task(\App\Tasks\SendWeeklyReportTask::class) + ->weekly() + ->fridays() + ->at('17:00') + ->timezone('Europe/Paris') + ->when(function () { + return app()->environment('production'); + }) + ->description('Envoi des rapports hebdomadaires'); + } - // ... autres méthodes + // ... autres méthodes } ```