Add URL-based PDF generation support
All checks were successful
Deploy / deploy (push) Successful in 8s
All checks were successful
Deploy / deploy (push) Successful in 8s
This commit is contained in:
parent
e3534dcefb
commit
09afbff2fd
5 changed files with 49 additions and 7 deletions
817
docs/IMPLEMENTATION_GUIDE.md
Normal file
817
docs/IMPLEMENTATION_GUIDE.md
Normal file
|
|
@ -0,0 +1,817 @@
|
|||
# Guide d'implémentation - Service Web2Print
|
||||
|
||||
Guide étape par étape pour déployer le service de conversion HTML vers PDF sur le VPS Infomaniak.
|
||||
|
||||
## Prérequis
|
||||
- Accès SSH au VPS
|
||||
- Accès à l'interface Infomaniak
|
||||
- Domaine `web2print.studio-variable.com` pointant vers le VPS
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 : Préparation du VPS
|
||||
|
||||
### 1.1 Connexion et vérification
|
||||
```bash
|
||||
# Vérifier Node.js et npm
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
# Vérifier Apache et PHP
|
||||
apache2 -v
|
||||
php -v
|
||||
```
|
||||
|
||||
### 1.2 Installation de Node.js (si nécessaire)
|
||||
```bash
|
||||
# Si Node.js n'est pas installé ou version < 14
|
||||
sudo apt update
|
||||
sudo apt install curl -y
|
||||
|
||||
# Installer Node.js via NodeSource (version LTS recommandée)
|
||||
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Vérifier l'installation
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
### 1.3 Installation de Paged.js CLI
|
||||
```bash
|
||||
# Installer pagedjs-cli globalement
|
||||
sudo npm install -g pagedjs-cli
|
||||
|
||||
# Vérifier l'installation (pagedjs-cli n'a pas d'option --version)
|
||||
npm list -g pagedjs-cli
|
||||
which pagedjs-cli
|
||||
|
||||
# Vérifier le chemin d'installation (noter pour la config PHP)
|
||||
which pagedjs-cli
|
||||
```
|
||||
|
||||
### 1.4 Tester Paged.js CLI
|
||||
```bash
|
||||
# Créer un fichier HTML de test
|
||||
cat > /tmp/test.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
@page { size: A4; margin: 2cm; }
|
||||
body { font-family: Arial, sans-serif; }
|
||||
h1 { color: #333; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test Paged.js CLI</h1>
|
||||
<p>Ceci est un test de génération PDF avec Paged.js.</p>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Générer un PDF de test
|
||||
pagedjs-cli /tmp/test.html -o /tmp/test.pdf
|
||||
|
||||
# Vérifier que le PDF est créé
|
||||
ls -lh /tmp/test.pdf
|
||||
file /tmp/test.pdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 : Structure du projet
|
||||
|
||||
### 2.1 Créer la structure des dossiers
|
||||
```bash
|
||||
# Créer le dossier du projet
|
||||
sudo mkdir -p /var/www/web2print
|
||||
cd /var/www/web2print
|
||||
|
||||
# Créer la structure
|
||||
sudo mkdir -p {public,config,logs,tmp}
|
||||
sudo mkdir -p src/{Controllers,Services,Middleware}
|
||||
|
||||
# Structure finale :
|
||||
# /var/www/web2print/
|
||||
# ├── public/
|
||||
# │ └── index.php
|
||||
# ├── src/
|
||||
# │ ├── Controllers/
|
||||
# │ ├── Services/
|
||||
# │ └── Middleware/
|
||||
# ├── config/
|
||||
# │ └── config.php
|
||||
# ├── logs/
|
||||
# └── tmp/
|
||||
```
|
||||
|
||||
### 2.2 Définir les permissions
|
||||
```bash
|
||||
# Propriétaire : www-data (utilisateur Apache)
|
||||
sudo chown -R www-data:www-data /var/www/web2print
|
||||
|
||||
# Permissions
|
||||
sudo chmod -R 755 /var/www/web2print
|
||||
sudo chmod -R 775 /var/www/web2print/logs
|
||||
sudo chmod -R 775 /var/www/web2print/tmp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 : Configuration Apache
|
||||
|
||||
### 3.1 Configurer le VirtualHost
|
||||
```bash
|
||||
# Créer le fichier de configuration
|
||||
sudo nano /etc/apache2/sites-available/web2print.conf
|
||||
```
|
||||
|
||||
Contenu du fichier `web2print.conf` :
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName web2print.studio-variable.com
|
||||
DocumentRoot /var/www/web2print/public
|
||||
|
||||
<Directory /var/www/web2print/public>
|
||||
Options -Indexes +FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Logs
|
||||
ErrorLog /var/www/web2print/logs/apache-error.log
|
||||
CustomLog /var/www/web2print/logs/apache-access.log combined
|
||||
|
||||
# Sécurité
|
||||
<FilesMatch "\.(env|config\.php)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### 3.2 Activer le site et modules nécessaires
|
||||
```bash
|
||||
# Activer le module rewrite
|
||||
sudo a2enmod rewrite
|
||||
|
||||
# Activer le site
|
||||
sudo a2ensite web2print.conf
|
||||
|
||||
# Vérifier la configuration
|
||||
sudo apache2ctl configtest
|
||||
|
||||
# Redémarrer Apache
|
||||
sudo systemctl restart apache2
|
||||
```
|
||||
|
||||
### 3.3 Configuration SSL avec Let's Encrypt (recommandé)
|
||||
```bash
|
||||
# Installer Certbot
|
||||
sudo apt install certbot python3-certbot-apache -y
|
||||
|
||||
# Obtenir et installer le certificat
|
||||
sudo certbot --apache -d web2print.studio-variable.com
|
||||
|
||||
# Le renouvellement automatique est configuré par défaut
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 : Configuration DNS (Interface Infomaniak)
|
||||
|
||||
### 4.1 Dans l'interface Infomaniak
|
||||
1. Aller dans la gestion des domaines
|
||||
2. Sélectionner le domaine `studio-variable.com`
|
||||
3. Accéder aux zones DNS
|
||||
4. Ajouter un enregistrement A :
|
||||
- **Nom** : `web2print`
|
||||
- **Type** : `A`
|
||||
- **Valeur** : `[IP du VPS]`
|
||||
- **TTL** : `3600`
|
||||
|
||||
### 4.2 Vérifier la propagation
|
||||
```bash
|
||||
# Attendre quelques minutes puis tester
|
||||
dig web2print.studio-variable.com
|
||||
curl -I http://web2print.studio-variable.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 : Implémentation du code PHP
|
||||
|
||||
### 5.1 Fichier de configuration
|
||||
```bash
|
||||
sudo nano /var/www/web2print/config/config.php
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```php
|
||||
<?php
|
||||
|
||||
return [
|
||||
// Clés API autorisées
|
||||
'api_keys' => [
|
||||
'votre-cle-api-secrete-generee-aleatoirement',
|
||||
// Ajouter d'autres clés si nécessaire
|
||||
],
|
||||
|
||||
// Chemins
|
||||
'tmp_dir' => '/var/www/web2print/tmp',
|
||||
'log_file' => '/var/www/web2print/logs/app.log',
|
||||
|
||||
// Paged.js CLI
|
||||
'pagedjs_bin' => '/usr/local/bin/pagedjs-cli', // Vérifier avec: which pagedjs-cli
|
||||
'pagedjs_timeout' => 60, // secondes
|
||||
|
||||
// Limites
|
||||
'max_html_size' => 5 * 1024 * 1024, // 5 MB
|
||||
'max_execution_time' => 90,
|
||||
|
||||
// Options PDF par défaut
|
||||
'pdf_defaults' => [
|
||||
'format' => 'A4',
|
||||
'margin' => '2cm',
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
### 5.2 Middleware d'authentification
|
||||
```bash
|
||||
sudo nano /var/www/web2print/src/Middleware/AuthMiddleware.php
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Web2Print\Middleware;
|
||||
|
||||
class AuthMiddleware
|
||||
{
|
||||
private array $config;
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function authenticate(): bool
|
||||
{
|
||||
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
||||
|
||||
if (empty($apiKey)) {
|
||||
$this->sendError(401, 'API key missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($apiKey, $this->config['api_keys'], true)) {
|
||||
$this->sendError(403, 'Invalid API key');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function sendError(int $code, string $message): void
|
||||
{
|
||||
http_response_code($code);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => $message]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 Service de génération PDF
|
||||
```bash
|
||||
sudo nano /var/www/web2print/src/Services/PdfGenerator.php
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Web2Print\Services;
|
||||
|
||||
class PdfGenerator
|
||||
{
|
||||
private array $config;
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function generate(string $html, ?string $css = null, array $options = []): string
|
||||
{
|
||||
// Créer un fichier HTML temporaire
|
||||
$htmlFile = $this->createTempFile($html, $css);
|
||||
$pdfFile = tempnam($this->config['tmp_dir'], 'pdf_') . '.pdf';
|
||||
|
||||
try {
|
||||
// Construire la commande Paged.js CLI
|
||||
$command = $this->buildCommand($htmlFile, $pdfFile, $options);
|
||||
|
||||
// Exécuter Paged.js CLI
|
||||
$output = [];
|
||||
$returnCode = 0;
|
||||
exec($command . ' 2>&1', $output, $returnCode);
|
||||
|
||||
if ($returnCode !== 0) {
|
||||
$this->log('Paged.js CLI error: ' . implode("\n", $output));
|
||||
throw new \Exception('PDF generation failed: ' . implode("\n", $output));
|
||||
}
|
||||
|
||||
// Lire le PDF généré
|
||||
if (!file_exists($pdfFile)) {
|
||||
throw new \Exception('PDF file not created');
|
||||
}
|
||||
|
||||
$pdfContent = file_get_contents($pdfFile);
|
||||
|
||||
return $pdfContent;
|
||||
|
||||
} finally {
|
||||
// Nettoyer les fichiers temporaires
|
||||
@unlink($htmlFile);
|
||||
@unlink($pdfFile);
|
||||
}
|
||||
}
|
||||
|
||||
private function createTempFile(string $html, ?string $css): string
|
||||
{
|
||||
$fullHtml = $html;
|
||||
|
||||
// Injecter le CSS dans le HTML si fourni
|
||||
if ($css) {
|
||||
$styleTag = "<style>{$css}</style>";
|
||||
if (stripos($html, '</head>') !== false) {
|
||||
$fullHtml = str_ireplace('</head>', $styleTag . '</head>', $html);
|
||||
} else {
|
||||
// Si pas de <head>, créer une structure HTML complète
|
||||
$fullHtml = "<!DOCTYPE html><html><head><meta charset='utf-8'>{$styleTag}</head><body>{$html}</body></html>";
|
||||
}
|
||||
}
|
||||
|
||||
// S'assurer que le HTML a une structure complète
|
||||
if (stripos($fullHtml, '<!DOCTYPE') === false) {
|
||||
$fullHtml = "<!DOCTYPE html><html><head><meta charset='utf-8'></head><body>{$fullHtml}</body></html>";
|
||||
}
|
||||
|
||||
$tempFile = tempnam($this->config['tmp_dir'], 'html_') . '.html';
|
||||
file_put_contents($tempFile, $fullHtml);
|
||||
|
||||
return $tempFile;
|
||||
}
|
||||
|
||||
private function buildCommand(string $htmlFile, string $pdfFile, array $options): string
|
||||
{
|
||||
$cmd = escapeshellcmd($this->config['pagedjs_bin']);
|
||||
$cmd .= ' ' . escapeshellarg($htmlFile);
|
||||
$cmd .= ' -o ' . escapeshellarg($pdfFile);
|
||||
|
||||
// Options supplémentaires pour Paged.js CLI
|
||||
// Note: Paged.js utilise les règles CSS @page pour le format
|
||||
// Les options sont limitées dans la CLI
|
||||
|
||||
// Timeout (millisecondes)
|
||||
if (!empty($options['timeout'])) {
|
||||
$cmd .= ' --timeout ' . (int)$options['timeout'];
|
||||
} else {
|
||||
$cmd .= ' --timeout ' . ($this->config['pagedjs_timeout'] * 1000);
|
||||
}
|
||||
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
private function log(string $message): void
|
||||
{
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
$logMessage = "[{$timestamp}] {$message}\n";
|
||||
file_put_contents($this->config['log_file'], $logMessage, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 Contrôleur principal
|
||||
```bash
|
||||
sudo nano /var/www/web2print/src/Controllers/GenerateController.php
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Web2Print\Controllers;
|
||||
|
||||
use Web2Print\Services\PdfGenerator;
|
||||
|
||||
class GenerateController
|
||||
{
|
||||
private PdfGenerator $generator;
|
||||
private array $config;
|
||||
|
||||
public function __construct(PdfGenerator $generator, array $config)
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
// Vérifier la méthode HTTP
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$this->sendError(405, 'Method not allowed');
|
||||
return;
|
||||
}
|
||||
|
||||
// Lire le body JSON
|
||||
$input = file_get_contents('php://input');
|
||||
|
||||
if (strlen($input) > $this->config['max_html_size']) {
|
||||
$this->sendError(413, 'Request too large');
|
||||
return;
|
||||
}
|
||||
|
||||
$data = json_decode($input, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
$this->sendError(400, 'Invalid JSON');
|
||||
return;
|
||||
}
|
||||
|
||||
// Valider les données
|
||||
if (empty($data['html'])) {
|
||||
$this->sendError(400, 'HTML content required');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Générer le PDF
|
||||
$pdf = $this->generator->generate(
|
||||
$data['html'],
|
||||
$data['css'] ?? null,
|
||||
$data['options'] ?? []
|
||||
);
|
||||
|
||||
// Retourner le PDF
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Length: ' . strlen($pdf));
|
||||
echo $pdf;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->sendError(500, 'PDF generation error: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function sendError(int $code, string $message): void
|
||||
{
|
||||
http_response_code($code);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => $message]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.5 Point d'entrée (index.php)
|
||||
```bash
|
||||
sudo nano /var/www/web2print/public/index.php
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```php
|
||||
<?php
|
||||
|
||||
// Autoloader simple
|
||||
spl_autoload_register(function ($class) {
|
||||
$prefix = 'Web2Print\\';
|
||||
$baseDir = __DIR__ . '/../src/';
|
||||
|
||||
$len = strlen($prefix);
|
||||
if (strncmp($prefix, $class, $len) !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$relativeClass = substr($class, $len);
|
||||
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
|
||||
|
||||
if (file_exists($file)) {
|
||||
require $file;
|
||||
}
|
||||
});
|
||||
|
||||
// Charger la configuration
|
||||
$config = require __DIR__ . '/../config/config.php';
|
||||
|
||||
// Définir le temps d'exécution max
|
||||
set_time_limit($config['max_execution_time']);
|
||||
|
||||
// Headers CORS (si nécessaire)
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: POST, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type, X-API-Key');
|
||||
|
||||
// Gérer preflight OPTIONS
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Authentification
|
||||
$auth = new \Web2Print\Middleware\AuthMiddleware($config);
|
||||
if (!$auth->authenticate()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Router simple
|
||||
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
|
||||
if ($uri === '/generate' || $uri === '/') {
|
||||
$generator = new \Web2Print\Services\PdfGenerator($config);
|
||||
$controller = new \Web2Print\Controllers\GenerateController($generator, $config);
|
||||
$controller->handle();
|
||||
} else {
|
||||
http_response_code(404);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['error' => 'Not found']);
|
||||
}
|
||||
```
|
||||
|
||||
### 5.6 Fichier .htaccess
|
||||
```bash
|
||||
sudo nano /var/www/web2print/public/.htaccess
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```apache
|
||||
# Activer le moteur de réécriture
|
||||
RewriteEngine On
|
||||
|
||||
# Rediriger toutes les requêtes vers index.php
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||
|
||||
# Sécurité
|
||||
<Files ".env">
|
||||
Require all denied
|
||||
</Files>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 : Génération de la clé API
|
||||
|
||||
### 6.1 Générer une clé sécurisée
|
||||
```bash
|
||||
# Sur le VPS
|
||||
openssl rand -hex 32
|
||||
# Exemple de sortie : a7f8e9d4c2b1a3f5e7d9c4b2a1f8e6d5c3b9a7f4e2d8c6b4a2f9e7d5c3b1a8f6
|
||||
```
|
||||
|
||||
### 6.2 Ajouter la clé dans la configuration
|
||||
```bash
|
||||
sudo nano /var/www/web2print/config/config.php
|
||||
```
|
||||
|
||||
Remplacer `'votre-cle-api-secrete-generee-aleatoirement'` par la clé générée.
|
||||
|
||||
### 6.3 Sécuriser le fichier de configuration
|
||||
```bash
|
||||
sudo chmod 640 /var/www/web2print/config/config.php
|
||||
sudo chown www-data:www-data /var/www/web2print/config/config.php
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 : Tests
|
||||
|
||||
### 7.1 Vérifier le chemin de Paged.js CLI
|
||||
```bash
|
||||
which pagedjs-cli
|
||||
# Mettre à jour 'pagedjs_bin' dans config.php si nécessaire
|
||||
```
|
||||
|
||||
### 7.2 Test avec curl - HTML simple
|
||||
```bash
|
||||
# Créer un fichier de test avec CSS Paged Media
|
||||
cat > /tmp/test-request.json << 'EOF'
|
||||
{
|
||||
"html": "<!DOCTYPE html><html><head><meta charset='utf-8'><style>@page { size: A4; margin: 2cm; } body { font-family: Arial; } h1 { color: #333; }</style></head><body><h1>Test PDF Paged.js</h1><p>Ceci est un test de génération PDF avec Paged.js CLI.</p></body></html>"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Tester l'API (remplacer YOUR_API_KEY)
|
||||
curl -X POST https://web2print.studio-variable.com/generate \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: YOUR_API_KEY" \
|
||||
-d @/tmp/test-request.json \
|
||||
--output /tmp/result.pdf
|
||||
|
||||
# Vérifier le PDF généré
|
||||
file /tmp/result.pdf
|
||||
ls -lh /tmp/result.pdf
|
||||
```
|
||||
|
||||
### 7.2b Test avec CSS séparé
|
||||
```bash
|
||||
# Test avec HTML et CSS séparés
|
||||
cat > /tmp/test-request-2.json << 'EOF'
|
||||
{
|
||||
"html": "<!DOCTYPE html><html><head><meta charset='utf-8'></head><body><h1>Test avec CSS séparé</h1><p>Le CSS est injecté séparément.</p></body></html>",
|
||||
"css": "@page { size: A4; margin: 2cm; } body { font-family: Georgia, serif; color: #444; } h1 { color: #d63031; border-bottom: 2px solid #d63031; padding-bottom: 10px; }"
|
||||
}
|
||||
EOF
|
||||
|
||||
curl -X POST https://web2print.studio-variable.com/generate \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: YOUR_API_KEY" \
|
||||
-d @/tmp/test-request-2.json \
|
||||
--output /tmp/result-2.pdf
|
||||
```
|
||||
|
||||
### 7.3 Test sans clé API (doit échouer)
|
||||
```bash
|
||||
curl -X POST https://web2print.studio-variable.com/generate \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"html": "<h1>Test</h1>"}'
|
||||
# Doit retourner : {"error":"API key missing"}
|
||||
```
|
||||
|
||||
### 7.4 Test avec mauvaise clé (doit échouer)
|
||||
```bash
|
||||
curl -X POST https://web2print.studio-variable.com/generate \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-API-Key: wrong-key" \
|
||||
-d '{"html": "<h1>Test</h1>"}'
|
||||
# Doit retourner : {"error":"Invalid API key"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 8 : Monitoring et maintenance
|
||||
|
||||
### 8.1 Rotation des logs
|
||||
```bash
|
||||
sudo nano /etc/logrotate.d/web2print
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```
|
||||
/var/www/web2print/logs/*.log {
|
||||
daily
|
||||
rotate 14
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 0640 www-data www-data
|
||||
sharedscripts
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 Nettoyage des fichiers temporaires
|
||||
```bash
|
||||
# Créer un script de nettoyage
|
||||
sudo nano /var/www/web2print/cleanup.sh
|
||||
```
|
||||
|
||||
Contenu :
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Nettoyer les fichiers temporaires de plus de 1 heure
|
||||
find /var/www/web2print/tmp -type f -mmin +60 -delete
|
||||
```
|
||||
|
||||
```bash
|
||||
# Rendre exécutable
|
||||
sudo chmod +x /var/www/web2print/cleanup.sh
|
||||
|
||||
# Ajouter au cron (toutes les heures)
|
||||
sudo crontab -e
|
||||
# Ajouter : 0 * * * * /var/www/web2print/cleanup.sh
|
||||
```
|
||||
|
||||
### 8.3 Surveiller les logs
|
||||
```bash
|
||||
# Logs Apache
|
||||
sudo tail -f /var/www/web2print/logs/apache-error.log
|
||||
|
||||
# Logs applicatifs
|
||||
sudo tail -f /var/www/web2print/logs/app.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 9 : Checklist de déploiement
|
||||
|
||||
- [ ] Node.js et npm installés
|
||||
- [ ] Paged.js CLI installé et fonctionnel
|
||||
- [ ] Structure de dossiers créée avec bonnes permissions
|
||||
- [ ] VirtualHost Apache configuré
|
||||
- [ ] SSL/TLS configuré (Let's Encrypt)
|
||||
- [ ] DNS configuré dans Infomaniak
|
||||
- [ ] Tous les fichiers PHP créés
|
||||
- [ ] Chemin `pagedjs_bin` vérifié dans config.php
|
||||
- [ ] Clé API générée et configurée
|
||||
- [ ] Tests d'API réussis (HTML simple + CSS séparé)
|
||||
- [ ] Rotation des logs configurée
|
||||
- [ ] Nettoyage automatique des fichiers temporaires configuré
|
||||
- [ ] Documentation de la clé API sauvegardée en lieu sûr
|
||||
|
||||
---
|
||||
|
||||
## Phase 10 : Optimisations futures (optionnel)
|
||||
|
||||
### 10.1 Rate limiting
|
||||
Ajouter un système de limitation de requêtes par clé API pour éviter les abus.
|
||||
|
||||
### 10.2 Cache
|
||||
Mettre en cache les PDFs générés si le même HTML est demandé plusieurs fois.
|
||||
|
||||
### 10.3 File d'attente
|
||||
Pour des volumes plus importants, implémenter une file d'attente avec des workers.
|
||||
|
||||
### 10.4 Monitoring avancé
|
||||
- Intégrer un système de monitoring (Prometheus, Grafana)
|
||||
- Alertes sur échecs de génération
|
||||
- Métriques de performance
|
||||
|
||||
---
|
||||
|
||||
## Ressources et documentation
|
||||
|
||||
- **Paged.js** : https://pagedjs.org/
|
||||
- **Paged.js CLI** : https://gitlab.coko.foundation/pagedjs/pagedjs-cli
|
||||
- **CSS Paged Media** : https://www.w3.org/TR/css-page-3/
|
||||
- **PHP exec()** : https://www.php.net/manual/fr/function.exec.php
|
||||
- **Apache VirtualHost** : https://httpd.apache.org/docs/2.4/vhosts/
|
||||
- **Let's Encrypt** : https://letsencrypt.org/
|
||||
|
||||
---
|
||||
|
||||
## Support et troubleshooting
|
||||
|
||||
### Erreur : "pagedjs-cli: command not found"
|
||||
```bash
|
||||
# Vérifier l'installation
|
||||
which pagedjs-cli
|
||||
npm list -g pagedjs-cli
|
||||
|
||||
# Réinstaller si nécessaire
|
||||
sudo npm install -g pagedjs-cli --force
|
||||
|
||||
# Si problème de PATH, vérifier où npm installe les binaires
|
||||
npm config get prefix
|
||||
# Les binaires sont dans: <prefix>/bin
|
||||
```
|
||||
|
||||
### Erreur : "Permission denied" lors de la génération
|
||||
```bash
|
||||
# Vérifier les permissions
|
||||
sudo chown -R www-data:www-data /var/www/web2print
|
||||
sudo chmod -R 775 /var/www/web2print/tmp
|
||||
sudo chmod -R 775 /var/www/web2print/logs
|
||||
```
|
||||
|
||||
### PDF vide ou erreur de génération
|
||||
- Vérifier les logs : `/var/www/web2print/logs/app.log`
|
||||
- Tester Paged.js CLI manuellement :
|
||||
```bash
|
||||
echo '<html><body>Test</body></html>' > /tmp/test.html
|
||||
pagedjs-cli /tmp/test.html -o /tmp/test.pdf
|
||||
```
|
||||
- Vérifier que Node.js est à jour (minimum v14)
|
||||
- S'assurer que le HTML contient `<!DOCTYPE html>` et une structure complète
|
||||
|
||||
### Erreur : "Timeout" lors de génération de gros documents
|
||||
- Augmenter `pagedjs_timeout` dans `config.php`
|
||||
- Augmenter `max_execution_time` dans `config.php`
|
||||
- Augmenter le timeout Apache si nécessaire :
|
||||
```bash
|
||||
sudo nano /etc/apache2/apache2.conf
|
||||
# Ajouter/modifier : Timeout 300
|
||||
sudo systemctl restart apache2
|
||||
```
|
||||
|
||||
### Les styles CSS ne sont pas appliqués
|
||||
- Vérifier que le CSS contient les règles `@page` pour Paged.js
|
||||
- S'assurer que les ressources externes (fonts, images) sont accessibles
|
||||
- Tester le HTML directement dans un navigateur avec Paged.js
|
||||
- Exemple de CSS Paged Media basique :
|
||||
```css
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 2cm;
|
||||
}
|
||||
@page :first {
|
||||
margin-top: 3cm;
|
||||
}
|
||||
```
|
||||
|
||||
### Différences de rendu entre front et back
|
||||
- Utiliser exactement la même version de Paged.js (front) et Paged.js CLI (back)
|
||||
- Vérifier la version installée : `npm list -g pagedjs-cli`
|
||||
- Les fonts doivent être identiques (utiliser web fonts ou fonts système communes)
|
||||
Loading…
Add table
Add a link
Reference in a new issue