From 67b17138f01dc1031ff782eaa4ed889b90a700c7 Mon Sep 17 00:00:00 2001 From: spwoodcock Date: Thu, 15 Jan 2026 13:39:49 +0000 Subject: [PATCH] docs: add docs for kubernetes deployment --- docs/self-hosting/index.md | 1 + docs/self-hosting/kubernetes.md | 157 ++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 docs/self-hosting/kubernetes.md diff --git a/docs/self-hosting/index.md b/docs/self-hosting/index.md index a492ec2..d817c04 100644 --- a/docs/self-hosting/index.md +++ b/docs/self-hosting/index.md @@ -81,6 +81,7 @@ Choose your platform: - [Nginx](/self-hosting/nginx) - [Apache](/self-hosting/apache) - [Docker](/self-hosting/docker) +- [Kubernetes](/self-hosting/kubernetes) - [CORS Proxy](/self-hosting/cors-proxy) - Required for digital signatures ## System Requirements diff --git a/docs/self-hosting/kubernetes.md b/docs/self-hosting/kubernetes.md new file mode 100644 index 0000000..183ad9e --- /dev/null +++ b/docs/self-hosting/kubernetes.md @@ -0,0 +1,157 @@ +# Deploy with Kubernetes + +Kubernetes may be overkill for a static site, but it can be a great fit if you already standardize on Helm + GitOps. + +> [!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 BentoPDF nginx images include these headers. In Kubernetes, **Ingress/Gateway controllers are also reverse proxies**, so ensure these headers are preserved (or add them at the edge). + +## Prereqs + +- Kubernetes cluster +- Helm v3 +- A BentoPDF nginx image (e.g. `ghcr.io/alam00000/bentopdf:`) that serves on **port 8080** + +## Deploy with Helm + +### Install from this repo (local chart) + +```bash +kubectl create namespace bentopdf + +helm upgrade --install bentopdf /path/to/bentopdf/chart \ + --namespace bentopdf \ + --set image.repository=ghcr.io/alam00000/bentopdf \ + --set image.tag=latest +``` + +### Install from GHCR (OCI chart) + +If the chart is published to GHCR as an OCI artifact: + +```bash +export GHCR_USERNAME="" + +helm upgrade --install bentopdf oci://ghcr.io/$GHCR_USERNAME/charts/bentopdf \ + --namespace bentopdf \ + --create-namespace \ + --version 0.1.0 \ + --set image.repository=ghcr.io/alam00000/bentopdf \ + --set image.tag=latest +``` + +## Expose it + +### Port-forward (quick test) + +```bash +kubectl -n bentopdf port-forward deploy/bentopdf 8080:8080 +``` + +### Ingress (optional) + +Enable Ingress (example for nginx-ingress): + +```yaml +ingress: + enabled: true + className: nginx + hosts: + - host: pdf.example.com + paths: + - path: / + pathType: Prefix +``` + +### Gateway API (optional) + +This chart supports Gateway API `Gateway` + `HTTPRoute`. + +Example (Cloudflare Gateway API operator): + +```yaml +gateway: + enabled: true + name: bento-tunnel + namespace: bentopdf + gatewayClassName: cloudflare + +httpRoute: + enabled: true + parentRefs: + - name: bento-tunnel + namespace: bentopdf + sectionName: http + hostnames: + - pdfs.example.com +``` + +## Ensuring the SharedArrayBuffer headers still work (Ingress/Gateway) + +### What "should" happen + +BentoPDF’s nginx config sets the required response headers. Most Ingress/Gateway controllers **pass upstream response headers through unchanged**. + +### What can break it + +- A controller/edge policy that **overrides** or **strips** response headers +- A "security headers" middleware that sets different COOP/COEP values + +### How to verify + +Run this against your public endpoint: + +```bash +curl -I https://pdf.example.com/ | egrep -i 'cross-origin-opener-policy|cross-origin-embedder-policy' +``` + +You should see: + +- `Cross-Origin-Opener-Policy: same-origin` +- `Cross-Origin-Embedder-Policy: require-corp` + +### If your Ingress controller does not preserve them + +Add the headers at the edge (controller-specific). Example for **nginx-ingress**: + +```yaml +ingress: + enabled: true + className: nginx + annotations: + nginx.ingress.kubernetes.io/configuration-snippet: | + add_header Cross-Origin-Opener-Policy "same-origin" always; + add_header Cross-Origin-Embedder-Policy "require-corp" always; +``` + +### If you’re using Gateway API and want to force-add headers + +Gateway API supports a `ResponseHeaderModifier` filter. You can attach it in `httpRoute.rules[*].filters`: + +```yaml +httpRoute: + enabled: true + hostnames: [pdf.example.com] + parentRefs: + - name: bento-tunnel + namespace: misc + sectionName: http + rules: + - matches: + - path: { type: PathPrefix, value: / } + filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + set: + - name: Cross-Origin-Opener-Policy + value: same-origin + - name: Cross-Origin-Embedder-Policy + value: require-corp +``` + +Support for specific filters depends on your Gateway controller; if a filter is ignored, add headers at the edge/controller layer instead.