docs: add docs for kubernetes deployment
This commit is contained in:
@@ -81,6 +81,7 @@ Choose your platform:
|
|||||||
- [Nginx](/self-hosting/nginx)
|
- [Nginx](/self-hosting/nginx)
|
||||||
- [Apache](/self-hosting/apache)
|
- [Apache](/self-hosting/apache)
|
||||||
- [Docker](/self-hosting/docker)
|
- [Docker](/self-hosting/docker)
|
||||||
|
- [Kubernetes](/self-hosting/kubernetes)
|
||||||
- [CORS Proxy](/self-hosting/cors-proxy) - Required for digital signatures
|
- [CORS Proxy](/self-hosting/cors-proxy) - Required for digital signatures
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
|
|||||||
157
docs/self-hosting/kubernetes.md
Normal file
157
docs/self-hosting/kubernetes.md
Normal file
@@ -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:<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.
|
||||||
Reference in New Issue
Block a user