158 lines
4.0 KiB
Markdown
158 lines
4.0 KiB
Markdown
|
|
# 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:<tag>`) 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="<github-org-or-user>"
|
|||
|
|
|
|||
|
|
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.
|