Files
bentopdf/docs/vi/self-hosting/nginx.md
T

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/javascript thứ hai: nginx phân tích mime.types theo 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êm mjs cạnh js.

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