6.5 KiB
Implementeren met Nginx
Host BentoPDF op je eigen server met Nginx.
Vereisten
- Ubuntu/Debian-server
- Nginx geïnstalleerd
- SSL-certificaat (aanbevolen: Let's Encrypt)
Stap 1: Bouw het project
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
npm install
npm run build
Om de huisstijl aan te passen, stel je omgevingsvariabelen in vóór het bouwen:
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
Stap 2: Bestanden kopiëren
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdf
Stap 3: Nginx-configuratie
Maak /etc/nginx/sites-available/bentopdf aan:
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
root /var/www/bentopdf;
index index.html;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/wasm;
gzip_min_length 1000;
# WASM MIME type
types {
application/wasm wasm;
}
# Required headers for SharedArrayBuffer (LibreOffice WASM)
# These must be on every response - especially HTML pages
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "cross-origin" always;
# Security 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;
# Pre-compressed LibreOffice WASM binary
location ~* /libreoffice-wasm/soffice\.wasm\.gz$ {
gzip off;
types {} default_type application/wasm;
add_header Content-Encoding gzip;
add_header Cache-Control "public, immutable";
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
}
# Pre-compressed LibreOffice WASM data
location ~* /libreoffice-wasm/soffice\.data\.gz$ {
gzip off;
types {} default_type application/octet-stream;
add_header Content-Encoding gzip;
add_header Cache-Control "public, immutable";
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|wasm)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
}
# SPA routing - serve index.html for all routes
location / {
try_files $uri $uri/ /index.html;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
}
}
Stap 4: De site inschakelen
sudo ln -s /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Stap 5: SSL met Let's Encrypt
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
Implementatie in een submap
Om te hosten op /pdf/:
location /pdf/ {
alias /var/www/bentopdf/;
try_files $uri $uri/ /pdf/index.html;
}
Bouw met:
BASE_URL=/pdf/ npm run build
Prestaties afstellen
Voeg toe aan nginx.conf:
http {
# Enable sendfile
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Increase buffer sizes
client_max_body_size 100M;
# Worker connections
worker_connections 2048;
}
Probleemoplossing
WASM wordt niet geladen
Zorg dat het MIME-type is ingesteld:
types {
application/wasm wasm;
}
PDF ondertekenen of formulierinvuller toont een lege viewer (.mjs MIME-fout)
Als de browserconsole het volgende toont:
Failed to load module script: The server responded with a non-JavaScript
MIME type of "application/octet-stream". Strict MIME type checking is
enforced for module scripts per HTML spec.
...en het mislukte verzoek eindigt op .mjs, dan mist in je nginx de koppeling .mjs → application/javascript. De meegeleverde PDF-viewer (gebruikt door PDF ondertekenen, PDF-formulier invullen en een paar andere tools) levert ES-modulebestanden met de extensie .mjs, en de standaard mime.types van nginx bevat die niet.
Los dit op door mjs toe te voegen aan de bestaande regel application/javascript in /etc/nginx/mime.types:
application/javascript js mjs;
Voeg GEEN tweede regel
application/javascripttoe: nginx leestmime.typesregel voor regel en slechts één koppeling van type naar extensie wint, dus een tweede regel wordt op sommige versies stilzwijgend genegeerd. Pas de bestaande regel aan doormjsnaastjstoe te voegen.
Of overschrijf het lokaal in je serverblok (geen globale bestandswijziging):
types {
application/javascript js mjs;
application/wasm wasm;
}
Laad nginx opnieuw na de wijziging:
sudo nginx -t && sudo systemctl reload nginx
Om te bevestigen: zoek in browser DevTools → tabblad Netwerk het mislukte .mjs-verzoek en controleer de responsheader Content-Type. Die moet nu application/javascript zijn, niet application/octet-stream.
Word/ODT/Excel naar PDF werkt niet
LibreOffice WASM vereist SharedArrayBuffer, waarvoor de headers Cross-Origin-Embedder-Policy en Cross-Origin-Opener-Policy nodig zijn. Ook is een veilige context nodig, dus http://localhost werkt voor lokaal testen, maar http://192.168.x.x of andere LAN-IP's vereisen meestal HTTPS. Let op: nginx add_header-directives in een location-blok overschrijven add_header-directives op serverniveau, ze worden niet samengevoegd. Elk location-blok met eigen add_header moet de COEP/COOP-headers bevatten.
Controleren met:
curl -I https://your-domain.com/ | grep -i cross-origin
Gebruik je een reverse proxy vóór nginx, zorg dan dat die deze headers behoudt.
502 Bad Gateway
Controleer de Nginx-foutlogboeken:
sudo tail -f /var/log/nginx/error.log