النشر باستخدام Nginx
استضف BentoPDF على خادمك الخاص باستخدام Nginx.
المتطلبات
- خادم Ubuntu/Debian
- Nginx مثبّت
- شهادة SSL (يُنصح بـ Let's Encrypt)
الخطوة 1: بناء المشروع
bash
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
npm install
npm run buildلتخصيص العلامة التجارية، اضبط متغيرات البيئة قبل البناء:
bash
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run buildالخطوة 2: نسخ الملفات
bash
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdfالخطوة 3: إعداد Nginx
أنشئ /etc/nginx/sites-available/bentopdf:
nginx
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;
}
}الخطوة 4: تفعيل الموقع
bash
sudo ln -s /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxالخطوة 5: SSL مع Let's Encrypt
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comالنشر في مجلد فرعي
للاستضافة على /pdf/:
nginx
location /pdf/ {
alias /var/www/bentopdf/;
try_files $uri $uri/ /pdf/index.html;
}ابنِ باستخدام:
bash
BASE_URL=/pdf/ npm run buildضبط الأداء
أضف إلى nginx.conf:
nginx
http {
# Enable sendfile
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Increase buffer sizes
client_max_body_size 100M;
# Worker connections
worker_connections 2048;
}استكشاف الأخطاء وإصلاحها
عدم تحميل WASM
تأكد من ضبط نوع MIME:
nginx
types {
application/wasm wasm;
}عارض توقيع PDF أو ملء النماذج فارغ (خطأ MIME لملفات .mjs)
إذا عرضت وحدة تحكم المتصفح:
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....وانتهى الطلب الفاشل بـ .mjs، فإن nginx لديك يفتقر إلى التعيين .mjs → application/javascript. يأتي عارض PDF المضمّن (الذي تستخدمه أدوات توقيع PDF وملء النماذج وبعض الأدوات الأخرى) بملفات وحدات ES بامتداد .mjs، ولا يتضمنها ملف mime.types الافتراضي في nginx.
أصلح ذلك بإضافة mjs إلى سطر application/javascript الموجود في /etc/nginx/mime.types:
nginx
application/javascript js mjs;لا تُضف سطرًا ثانيًا لـ
application/javascript: يحلل nginx الملفmime.typesسطرًا بسطر ويفوز تعيين واحد فقط من النوع إلى الامتداد، لذا يُتجاهل السطر الثاني بصمت في بعض الإصدارات. عدّل السطر الموجود لإضافةmjsبجانبjs.
أو تجاوزه محليًا داخل كتلة server (دون تعديل الملف العام):
nginx
types {
application/javascript js mjs;
application/wasm wasm;
}أعد تحميل nginx بعد التغيير:
bash
sudo nginx -t && sudo systemctl reload nginxللتأكد: في DevTools بالمتصفح، افتح تبويب Network، وابحث عن طلب .mjs الفاشل وتحقق من ترويسة الاستجابة Content-Type. يجب أن تكون الآن application/javascript وليس application/octet-stream.
تحويل Word/ODT/Excel إلى PDF لا يعمل
يتطلب LibreOffice WASM وجود SharedArrayBuffer، الذي يحتاج إلى ترويستي Cross-Origin-Embedder-Policy وCross-Origin-Opener-Policy. كما يحتاج إلى سياق آمن، لذا يعمل http://localhost للاختبار المحلي، بينما يتطلب http://192.168.x.x أو غيره من عناوين IP المحلية عادةً HTTPS. لاحظ أن توجيهات add_header في nginx داخل كتلة location تستبدل توجيهات add_header على مستوى server ولا تُدمج معها. يجب أن تتضمن كل كتلة location لها add_header خاص بها ترويستي COEP/COOP.
تحقق باستخدام:
bash
curl -I https://your-domain.com/ | grep -i cross-originإذا كنت تستخدم وكيلًا عكسيًا أمام nginx، فتأكد من أنه يحافظ على هذه الترويسات.
502 Bad Gateway
افحص سجلات أخطاء Nginx:
bash
sudo tail -f /var/log/nginx/error.log