6.8 KiB
Triển khai với Nginx
Lưu trữ BentoPDF trên máy chủ của riêng bạn bằng Nginx.
Điều kiện tiên quyết
- Máy chủ Ubuntu/Debian
- Đã cài Nginx
- Chứng chỉ SSL (khuyến nghị: Let's Encrypt)
Bước 1: Dựng dự án
git clone https://github.com/alam00000/bentopdf.git
cd bentopdf
npm install
npm run build
Để tùy chỉnh thương hiệu, hãy đặt biến môi trường trước khi dựng:
VITE_BRAND_NAME="AcmePDF" VITE_BRAND_LOGO="images/acme-logo.svg" npm run build
Bước 2: Sao chép tệp
sudo mkdir -p /var/www/bentopdf
sudo cp -r dist/* /var/www/bentopdf/
sudo chown -R www-data:www-data /var/www/bentopdf
Bước 3: Cấu hình Nginx
Tạo /etc/nginx/sites-available/bentopdf:
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;
}
}
Bước 4: Bật trang web
sudo ln -s /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Bước 5: SSL với Let's Encrypt
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com
Triển khai vào thư mục con
Để lưu trữ tại /pdf/:
location /pdf/ {
alias /var/www/bentopdf/;
try_files $uri $uri/ /pdf/index.html;
}
Dựng với:
BASE_URL=/pdf/ npm run build
Tinh chỉnh hiệu năng
Thêm vào 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;
}
Khắc phục sự cố
WASM không tải được
Đảm bảo đã đặt kiểu MIME:
types {
application/wasm wasm;
}
Ký PDF hoặc Form Filler hiển thị trình xem trống (lỗi MIME .mjs)
Nếu bảng điều khiển trình duyệt hiển thị:
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.
...và yêu cầu bị lỗi có đuôi .mjs, nginx của bạn đang thiếu ánh xạ .mjs → application/javascript. Trình xem PDF đi kèm (được dùng bởi Ký PDF, Form Filler và một vài công cụ khác) có các tệp module ES với phần mở rộng .mjs, và mime.types mặc định của nginx không bao gồm chúng.
Hãy khắc phục bằng cách thêm mjs vào dòng application/javascript hiện có trong /etc/nginx/mime.types:
application/javascript js mjs;
KHÔNG thêm dòng
application/javascriptthứ hai: nginx phân tíchmime.typestheo từng dòng và chỉ một ánh xạ kiểu sang phần mở rộng có hiệu lực, nên dòng thứ hai bị bỏ qua âm thầm trên một số phiên bản. Hãy sửa dòng hiện có để thêmmjscạnhjs.
Hoặc ghi đè cục bộ trong khối server của bạn (không sửa tệp toàn cục):
types {
application/javascript js mjs;
application/wasm wasm;
}
Tải lại nginx sau khi thay đổi:
sudo nginx -t && sudo systemctl reload nginx
Để xác nhận: trong DevTools của trình duyệt → tab Network, tìm yêu cầu .mjs bị lỗi và kiểm tra header phản hồi Content-Type. Giờ nó phải là application/javascript, không phải application/octet-stream.
Chuyển Word/ODT/Excel sang PDF không hoạt động
LibreOffice WASM cần SharedArrayBuffer, thứ đòi hỏi các header Cross-Origin-Embedder-Policy và Cross-Origin-Opener-Policy. Nó cũng cần ngữ cảnh bảo mật, nên http://localhost dùng được để thử cục bộ nhưng http://192.168.x.x hay các IP LAN khác thường cần HTTPS. Lưu ý rằng các chỉ thị nginx add_header trong khối location ghi đè các chỉ thị add_header ở cấp server, chúng không được gộp lại. Mỗi khối location có add_header riêng phải bao gồm các header COEP/COOP.
Kiểm tra bằng:
curl -I https://your-domain.com/ | grep -i cross-origin
Nếu dùng reverse proxy đặt trước nginx, hãy đảm bảo nó giữ nguyên các header này.
502 Bad Gateway
Kiểm tra nhật ký lỗi của Nginx:
sudo tail -f /var/log/nginx/error.log