Skip to content

Commit fb177bf

Browse files
committed
feat(chrome): adding new option to enable chrome headless to run pdf exports
1 parent bf60bff commit fb177bf

8 files changed

Lines changed: 288 additions & 34 deletions

File tree

charts/xwiki/templates/_helpers.tpl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,26 @@ Create a default fully qualified app name for Remote Chrome.
2121
{{- printf "%s-%s" (include "xwiki.fullname" .) "chrome" | trunc 63 | trimSuffix "-" -}}
2222
{{- end }}
2323

24+
{{/*
25+
Chrome Common labels
26+
*/}}
27+
{{- define "chrome.labels" -}}
28+
helm.sh/chart: {{ include "common.names.chart" . }}
29+
{{ include "chrome.selectorLabels" . }}
30+
{{- if .Chart.AppVersion }}
31+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
32+
{{- end }}
33+
app.kubernetes.io/managed-by: {{ .Release.Service }}
34+
{{- end }}
35+
36+
{{/*
37+
Chrome Selector labels
38+
*/}}
39+
{{- define "chrome.selectorLabels" -}}
40+
app.kubernetes.io/name: {{ include "common.names.name" . }}-chrome
41+
app.kubernetes.io/instance: {{ .Release.Name }}
42+
{{- end }}
43+
2444
{{- define "solr.fullname" -}}
2545
{{- printf "%s-solr" (include "common.names.fullname" .) }}
2646
{{- end }}

charts/xwiki/templates/chrome-deployment.yaml

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,18 @@ kind: Deployment
44
metadata:
55
name: {{ include "chrome.fullname" . }}
66
labels:
7-
{{- include "xwiki.labels" . | nindent 4 }}
8-
app.kubernetes.io/component: chrome
7+
{{- include "chrome.labels" . | nindent 4 }}
98
spec:
109
{{- if not .Values.chrome.autoscaling.enabled }}
1110
replicas: {{ .Values.chrome.replicaCount }}
1211
{{- end }}
1312
selector:
1413
matchLabels:
15-
{{- include "xwiki.selectorLabels" . | nindent 6 }}
16-
app.kubernetes.io/component: chrome
14+
{{- include "chrome.selectorLabels" . | nindent 6 }}
1715
template:
1816
metadata:
1917
labels:
20-
{{- include "xwiki.selectorLabels" . | nindent 8 }}
21-
app.kubernetes.io/component: chrome
18+
{{- include "chrome.selectorLabels" . | nindent 8 }}
2219
{{- if .Values.chrome.podAnnotations }}
2320
annotations:
2421
{{- toYaml .Values.chrome.podAnnotations | nindent 8 }}
@@ -35,12 +32,26 @@ spec:
3532
image: {{ include "chrome.imageName" . }}
3633
imagePullPolicy: {{ .Values.chrome.image.pullPolicy }}
3734
args:
35+
{{- if .Values.chrome.nginx.enabled }}
36+
- "--remote-debugging-address=127.0.0.1"
37+
- "--remote-debugging-port={{ .Values.chrome.internalPort }}"
38+
{{- range .Values.chrome.args }}
39+
{{- if not (or (hasPrefix "--remote-debugging-address" .) (hasPrefix "--remote-debugging-port" .)) }}
40+
- {{ . | quote }}
41+
{{- end }}
42+
{{- end }}
43+
{{- else }}
3844
{{- toYaml .Values.chrome.args | nindent 12 }}
3945
- --remote-debugging-port={{ .Values.chrome.service.port }}
46+
{{- end }}
4047
ports:
48+
{{- if .Values.chrome.nginx.enabled }}
49+
- name: chrome-internal
50+
containerPort: {{ .Values.chrome.internalPort }}
51+
{{- else }}
4152
- name: {{ .Values.chrome.service.portName }}
4253
containerPort: {{ .Values.chrome.service.port }}
43-
protocol: TCP
54+
{{- end }}
4455
volumeMounts:
4556
- name: tmp-dir
4657
mountPath: /tmp
@@ -58,6 +69,23 @@ spec:
5869
resources:
5970
{{- toYaml .Values.chrome.resources | nindent 12 }}
6071
{{- end }}
72+
{{- if .Values.chrome.nginx.enabled }}
73+
- name: nginx
74+
image: "{{ .Values.chrome.nginx.image.registry }}/{{ .Values.chrome.nginx.image.repository }}:{{ .Values.chrome.nginx.image.tag }}"
75+
imagePullPolicy: {{ .Values.chrome.nginx.image.pullPolicy }}
76+
ports:
77+
- name: {{ .Values.chrome.service.portName }}
78+
containerPort: {{ .Values.chrome.service.port }}
79+
protocol: TCP
80+
volumeMounts:
81+
- name: nginx-config
82+
mountPath: /etc/nginx/nginx.conf
83+
subPath: nginx.conf
84+
{{- if .Values.chrome.nginx.resources }}
85+
resources:
86+
{{- toYaml .Values.chrome.nginx.resources | nindent 12 }}
87+
{{- end }}
88+
{{- end }}
6189
{{- with .Values.chrome.nodeSelector }}
6290
nodeSelector:
6391
{{- toYaml . | nindent 8 }}
@@ -77,4 +105,9 @@ spec:
77105
emptyDir:
78106
medium: Memory
79107
sizeLimit: 256Mi
108+
{{- if .Values.chrome.nginx.enabled }}
109+
- name: nginx-config
110+
configMap:
111+
name: {{ include "chrome.fullname" . }}-nginx
112+
{{- end }}
80113
{{- end }}

charts/xwiki/templates/chrome-hpa.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ kind: HorizontalPodAutoscaler
44
metadata:
55
name: {{ include "chrome.fullname" . }}
66
labels:
7-
{{- include "xwiki.labels" . | nindent 4 }}
8-
app.kubernetes.io/component: chrome
7+
{{- include "chrome.labels" . | nindent 4 }}
98
spec:
109
scaleTargetRef:
1110
apiVersion: apps/v1
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{{- if and .Values.chrome.enabled .Values.chrome.ingress.enabled -}}
2+
{{- $fullName := include "chrome.fullname" . -}}
3+
{{- $svcPort := .Values.chrome.service.port -}}
4+
{{- if and .Values.chrome.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
5+
{{- if not (hasKey .Values.chrome.ingress.annotations "kubernetes.io/ingress.class") }}
6+
{{- $_ := set .Values.chrome.ingress.annotations "kubernetes.io/ingress.class" .Values.chrome.ingress.className}}
7+
{{- end }}
8+
{{- end }}
9+
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
10+
apiVersion: networking.k8s.io/v1
11+
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
12+
apiVersion: networking.k8s.io/v1beta1
13+
{{- else -}}
14+
apiVersion: extensions/v1beta1
15+
{{- end }}
16+
kind: Ingress
17+
metadata:
18+
name: {{ $fullName }}
19+
labels:
20+
{{- include "chrome.labels" . | nindent 4 }}
21+
annotations:
22+
{{- if .Values.chrome.ingress.annotations }}
23+
{{ toYaml .Values.chrome.ingress.annotations | indent 4 }}
24+
{{- end }}
25+
{{- if .Values.commonAnnotations }}
26+
{{ toYaml .Values.commonAnnotations | indent 4 }}
27+
{{- end }}
28+
spec:
29+
{{- if and .Values.chrome.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
30+
ingressClassName: {{ .Values.chrome.ingress.className }}
31+
{{- end }}
32+
{{- if .Values.chrome.ingress.tls }}
33+
tls:
34+
{{- range .Values.chrome.ingress.tls }}
35+
- hosts:
36+
{{- range .hosts }}
37+
- {{ . | quote }}
38+
{{- end }}
39+
secretName: {{ .secretName }}
40+
{{- end }}
41+
{{- end }}
42+
rules:
43+
{{- range .Values.chrome.ingress.hosts }}
44+
- host: {{ .host | quote }}
45+
http:
46+
paths:
47+
{{- range .paths }}
48+
- path: {{ .path }}
49+
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
50+
pathType: {{ .pathType }}
51+
{{- end }}
52+
backend:
53+
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
54+
service:
55+
name: {{ $fullName }}
56+
port:
57+
number: {{ $svcPort }}
58+
{{- else }}
59+
serviceName: {{ $fullName }}
60+
servicePort: {{ $svcPort }}
61+
{{- end }}
62+
{{- end }}
63+
{{- end }}
64+
{{- end -}}

charts/xwiki/templates/chrome-networkpolicy.yaml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ kind: NetworkPolicy
44
metadata:
55
name: {{ include "chrome.fullname" . }}
66
labels:
7-
{{- include "xwiki.labels" . | nindent 4 }}
8-
app.kubernetes.io/component: chrome
7+
{{- include "chrome.labels" . | nindent 4 }}
98
spec:
109
podSelector:
1110
matchLabels:
12-
{{- include "xwiki.selectorLabels" . | nindent 6 }}
13-
app.kubernetes.io/component: chrome
11+
{{- include "chrome.selectorLabels" . | nindent 6 }}
1412
policyTypes:
1513
- Ingress
1614
- Egress
@@ -23,7 +21,18 @@ spec:
2321
ports:
2422
- protocol: TCP
2523
port: {{ .Values.chrome.service.port }}
24+
{{- with .Values.chrome.networkPolicy.ingress }}
25+
{{- toYaml . | nindent 4 }}
26+
{{- end }}
2627
egress:
28+
# Allow egress to XWiki pods so Chrome can fetch pages for PDF rendering
29+
- to:
30+
- podSelector:
31+
matchLabels:
32+
{{- include "xwiki.selectorLabels" . | nindent 14 }}
33+
ports:
34+
- protocol: TCP
35+
port: {{ .Values.service.internalPort }}
2736
{{- with .Values.chrome.networkPolicy.egress }}
2837
{{- toYaml . | nindent 4 }}
2938
{{- end }}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{{- if and .Values.chrome.enabled .Values.chrome.nginx.enabled }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ include "chrome.fullname" . }}-nginx
6+
labels:
7+
{{- include "chrome.labels" . | nindent 4 }}
8+
data:
9+
nginx.conf: |
10+
worker_processes 1;
11+
pid /tmp/nginx.pid;
12+
error_log /dev/stderr warn;
13+
14+
events {
15+
worker_connections 1024;
16+
}
17+
18+
http {
19+
access_log /dev/stdout;
20+
21+
# Temp paths so nginx can run as non-root
22+
client_body_temp_path /tmp/client_body;
23+
proxy_temp_path /tmp/proxy;
24+
25+
# Map Upgrade header to the correct Connection value for WebSocket support
26+
map $http_upgrade $connection_upgrade {
27+
default upgrade;
28+
'' close;
29+
}
30+
31+
# Zone for total simultaneous connection limit (all clients share this pool)
32+
limit_conn_zone $server_addr zone=chrome_conn:1m;
33+
34+
server {
35+
listen {{ .Values.chrome.service.port }};
36+
37+
location / {
38+
limit_conn chrome_conn {{ .Values.chrome.nginx.maxConnections }};
39+
40+
proxy_pass http://127.0.0.1:{{ .Values.chrome.internalPort }};
41+
proxy_http_version 1.1;
42+
43+
# Chrome DevTools only accepts 'localhost' or an IP in the Host header.
44+
# We use internalPort so Chrome builds webSocketDebuggerUrl as
45+
# ws://localhost:<internalPort>/... which sub_filter rewrites below.
46+
proxy_set_header Host "localhost:{{ .Values.chrome.internalPort }}";
47+
proxy_set_header X-Real-IP $remote_addr;
48+
49+
# WebSocket: forward Upgrade/Connection headers
50+
proxy_set_header Upgrade $http_upgrade;
51+
proxy_set_header Connection $connection_upgrade;
52+
53+
# Disable response compression so sub_filter can rewrite JSON bodies
54+
proxy_set_header Accept-Encoding "";
55+
56+
# Chrome embeds its Host header in webSocketDebuggerUrl responses.
57+
# Rewrite localhost:<internalPort> → <service>:<servicePort> so XWiki
58+
# receives a URL it can actually reach through this proxy.
59+
sub_filter_types application/json;
60+
sub_filter_once off;
61+
sub_filter 'localhost:{{ .Values.chrome.internalPort }}' '{{ include "chrome.fullname" . }}:{{ .Values.chrome.service.port }}';
62+
63+
proxy_read_timeout 3600s;
64+
proxy_send_timeout 3600s;
65+
}
66+
}
67+
}
68+
{{- end }}

charts/xwiki/templates/chrome-service.yaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,27 @@ kind: Service
44
metadata:
55
name: {{ include "chrome.fullname" . }}
66
labels:
7-
{{- include "xwiki.labels" . | nindent 4 }}
8-
app.kubernetes.io/component: chrome
7+
{{- include "chrome.labels" . | nindent 4 }}
98
{{- if .Values.chrome.service.annotations }}
109
annotations:
10+
{{- if .Values.commonAnnotations }}
11+
{{ toYaml .Values.commonAnnotations | indent 4 }}
12+
{{- end }}
1113
{{- toYaml .Values.chrome.service.annotations | nindent 4 }}
12-
{{- end }}
14+
{{- end }}
1315
spec:
1416
type: {{ .Values.chrome.service.type }}
17+
{{- if .Values.chrome.nginx.enabled }}
18+
sessionAffinity: ClientIP
19+
sessionAffinityConfig:
20+
clientIP:
21+
timeoutSeconds: {{ .Values.chrome.service.sessionAffinityTimeoutSeconds }}
22+
{{- end }}
1523
ports:
1624
- port: {{ .Values.chrome.service.port }}
1725
targetPort: {{ .Values.chrome.service.port }}
1826
protocol: TCP
1927
name: {{ .Values.chrome.service.portName }}
2028
selector:
21-
{{- include "xwiki.selectorLabels" . | nindent 4 }}
22-
app.kubernetes.io/component: chrome
29+
{{- include "chrome.selectorLabels" . | nindent 4 }}
2330
{{- end }}

0 commit comments

Comments
 (0)