fix: nginx.conf for docker deployment

This commit is contained in:
abdullahalam123
2026-01-04 00:56:06 +05:30
parent 771de32cf0
commit d9561d79b9
3 changed files with 23 additions and 3 deletions

View File

@@ -2,6 +2,15 @@
The easiest way to self-host BentoPDF in a production environment. The easiest way to self-host BentoPDF in a production environment.
> [!IMPORTANT]
> **Required Headers for Office File Conversion**
>
> LibreOffice-based tools (Word, Excel, PowerPoint conversion) require these HTTP headers for `SharedArrayBuffer` support:
> - `Cross-Origin-Opener-Policy: same-origin`
> - `Cross-Origin-Embedder-Policy: require-corp`
>
> The official Docker images include these headers. If using a reverse proxy (Traefik, Caddy, etc.), ensure these headers are preserved or added.
## Quick Start ## Quick Start
```bash ```bash
@@ -106,6 +115,10 @@ services:
- "traefik.http.routers.bentopdf.entrypoints=websecure" - "traefik.http.routers.bentopdf.entrypoints=websecure"
- "traefik.http.routers.bentopdf.tls.certresolver=letsencrypt" - "traefik.http.routers.bentopdf.tls.certresolver=letsencrypt"
- "traefik.http.services.bentopdf.loadbalancer.server.port=8080" - "traefik.http.services.bentopdf.loadbalancer.server.port=8080"
# Required headers for SharedArrayBuffer (LibreOffice WASM)
- "traefik.http.routers.bentopdf.middlewares=bentopdf-headers"
- "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Opener-Policy=same-origin"
- "traefik.http.middlewares.bentopdf-headers.headers.customresponseheaders.Cross-Origin-Embedder-Policy=require-corp"
restart: unless-stopped restart: unless-stopped
``` ```
@@ -135,6 +148,8 @@ Caddyfile:
``` ```
pdf.example.com { pdf.example.com {
reverse_proxy bentopdf:8080 reverse_proxy bentopdf:8080
header Cross-Origin-Opener-Policy "same-origin"
header Cross-Origin-Embedder-Policy "require-corp"
} }
``` ```

View File

@@ -96,6 +96,7 @@ http {
add_header X-Content-Type-Options "nosniff" always; add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always; add_header X-XSS-Protection "1; mode=block" always;
add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "cross-origin" always; add_header Cross-Origin-Resource-Policy "cross-origin" always;
} }
} }

View File

@@ -6,7 +6,7 @@
*/ */
import { WorkerBrowserConverter } from '@matbee/libreoffice-converter/browser'; import { WorkerBrowserConverter } from '@matbee/libreoffice-converter/browser';
import { getWasmBaseUrl } from '../config/wasm-cdn-config.js'; import { getWasmBaseUrl, getWasmFallbackUrl, isCdnEnabled } from '../config/wasm-cdn-config.js';
export interface LoadProgress { export interface LoadProgress {
phase: 'loading' | 'initializing' | 'converting' | 'complete' | 'ready'; phase: 'loading' | 'initializing' | 'converting' | 'complete' | 'ready';
@@ -24,10 +24,12 @@ export class LibreOfficeConverter {
private initialized = false; private initialized = false;
private initializing = false; private initializing = false;
private basePath: string; private basePath: string;
private localPath: string;
constructor(basePath?: string) { constructor(basePath?: string) {
// Use CDN if available, otherwise use provided basePath or default local path // Use CDN if available, otherwise use provided basePath or default local path
this.basePath = basePath || getWasmBaseUrl('libreoffice'); this.basePath = basePath || getWasmBaseUrl('libreoffice');
this.localPath = getWasmFallbackUrl('libreoffice');
} }
async initialize(onProgress?: ProgressCallback): Promise<void> { async initialize(onProgress?: ProgressCallback): Promise<void> {
@@ -47,12 +49,14 @@ export class LibreOfficeConverter {
try { try {
progressCallback?.({ phase: 'loading', percent: 0, message: 'Loading conversion engine...' }); progressCallback?.({ phase: 'loading', percent: 0, message: 'Loading conversion engine...' });
const workerPath = isCdnEnabled() ? this.localPath : this.basePath;
this.converter = new WorkerBrowserConverter({ this.converter = new WorkerBrowserConverter({
sofficeJs: `${this.basePath}soffice.js`, sofficeJs: `${this.basePath}soffice.js`,
sofficeWasm: `${this.basePath}soffice.wasm.gz`, sofficeWasm: `${this.basePath}soffice.wasm.gz`,
sofficeData: `${this.basePath}soffice.data.gz`, sofficeData: `${this.basePath}soffice.data.gz`,
sofficeWorkerJs: `${this.basePath}soffice.worker.js`, sofficeWorkerJs: `${workerPath}soffice.worker.js`,
browserWorkerJs: `${this.basePath}browser.worker.global.js`, browserWorkerJs: `${workerPath}browser.worker.global.js`,
verbose: false, verbose: false,
onProgress: (info: { phase: string; percent: number; message: string }) => { onProgress: (info: { phase: string; percent: number; message: string }) => {
if (progressCallback && !this.initialized) { if (progressCallback && !this.initialized) {