Skip to content

Commit 93d937a

Browse files
committed
[ADD] reverse proxy
1 parent 045cb39 commit 93d937a

10 files changed

Lines changed: 366 additions & 1 deletion

File tree

charts/adhoc-odoo/v0.3.0/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
Features:
66

7+
- reverse Proxy:
8+
- add nginx to serve files
9+
710
## *0.2.9*
811

912
Features:

charts/adhoc-odoo/v0.3.0/questions.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ questions:
468468
type: "string"
469469
required: false
470470
default: ""
471+
- variable: ingress.enableReverseProxy
472+
group: "Ingress"
473+
label: "Enable Reverse Proxy"
474+
description: "put an nginx in front of odoo"
475+
type: "boolean"
476+
required: false
477+
default: false
471478

472479
# Adhoc
473480
- variable: adhoc.serviceLevel

charts/adhoc-odoo/v0.3.0/templates/_helpers.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,4 @@ We remove initial number to compile with [a-z]([-a-z0-9]*[a-z0-9])?
9797
{{- $original := (include "adhoc-odoo.fullname" .) | lower }}
9898
{{- $original = regexReplaceAll "^[0-9]+" $original "" }}
9999
{{- regexReplaceAll "[^a-z0-9-]" $original "" }}
100-
{{- end }}
100+
{{- end }}

charts/adhoc-odoo/v0.3.0/templates/deployment.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ spec:
125125
mountPath: /etc/hosts
126126
subPath: hosts
127127
{{- end }}
128+
{{- if .Values.ingress.enableReverseProxy }}
129+
- name: odoo-sendfile-conf
130+
mountPath: /home/odoo/.resources/conf.d/odoo-send-file.conf
131+
subPath: odoo-send-file.conf
132+
{{- end }}
128133
affinity:
129134
podAntiAffinity:
130135
preferredDuringSchedulingIgnoredDuringExecution:
@@ -187,6 +192,11 @@ spec:
187192
configMap:
188193
name: {{ include "adhoc-odoo.fullname" . }}-hosts
189194
{{- end }}
195+
{{- if .Values.ingress.enableReverseProxy }}
196+
- name: odoo-sendfile-conf
197+
configMap:
198+
name: {{ include "adhoc-odoo.fullname" . }}-odoo-sendfile-conf
199+
{{- end }}
190200
{{- if eq .Values.storage.location "fuse" }}
191201
- name: gcs-fuse-csi-ephemeral
192202
csi:

charts/adhoc-odoo/v0.3.0/templates/ingress.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ spec:
5757
pathType: Prefix
5858
backend:
5959
service:
60+
{{- if .Values.ingress.enableReverseProxy }}
61+
name: {{ include "adhoc-odoo.serviceNameSuffix" . }}-nginx
62+
{{- else }}
6063
name: {{ $fullName }}-http
64+
{{- end }}
6165
port:
6266
number: 80
6367
{{- if gt $usewebsocket 0 }}
@@ -69,7 +73,11 @@ spec:
6973
{{- end }}
7074
backend:
7175
service:
76+
{{- if .Values.ingress.enableReverseProxy }}
77+
name: {{ include "adhoc-odoo.serviceNameSuffix" . }}-nginx
78+
{{- else }}
7279
name: {{ $fullName }}-websocket
80+
{{- end }}
7381
port:
7482
number: 80
7583
{{- end }}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{{/*
2+
Selector labels
3+
*/}}
4+
{{- define "adhoc-odoo.nxselectorLabels" -}}
5+
app.kubernetes.io/name: {{ include "adhoc-odoo.name" . }}-nx
6+
app.kubernetes.io/instance: {{ .Release.Name }}
7+
{{- end }}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
{{- if .Values.ingress.enableReverseProxy }}
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: {{ include "adhoc-odoo.fullname" . }}-nginx-config
6+
labels:
7+
{{- include "adhoc-odoo.labels" . | nindent 4 }}
8+
data:
9+
nginx.conf: |
10+
events {
11+
worker_connections 1024;
12+
}
13+
http {
14+
default_type application/octet-stream;
15+
16+
sendfile on;
17+
proxy_redirect off;
18+
server_tokens off;
19+
20+
access_log off;
21+
# access_log /dev/stdout;
22+
# error_log /dev/stderr;
23+
24+
keepalive_timeout 65;
25+
tcp_nodelay on;
26+
27+
# Proxy optimizations
28+
proxy_buffers 32 8k;
29+
proxy_buffer_size 4k;
30+
proxy_busy_buffers_size 8k;
31+
proxy_max_temp_file_size 2048m;
32+
proxy_temp_file_write_size 64k;
33+
34+
# Proxy cache
35+
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:10m max_size=10g inactive=60m;
36+
37+
# Default value '4 8k' is raising a '414 Request-URI Too Large' error
38+
# when '/web/webclient/translations/' is requested with a lot of module names
39+
# as GET parameters (performed on user login), rendering a blank page.
40+
# Source: https://github.com/camptocamp/docker-odoo-nginx/blob/891ad970/9.0/templates/nginx.conf.tmpl#L46-L50
41+
large_client_header_buffers 4 12k;
42+
43+
types_hash_max_size 1024;
44+
types_hash_bucket_size 512;
45+
46+
server_names_hash_bucket_size 64;
47+
server_names_hash_max_size 512;
48+
49+
# Gzip
50+
gzip on;
51+
gzip_http_version 1.0;
52+
gzip_proxied any;
53+
gzip_min_length 500;
54+
gzip_disable "MSIE [1-6]\.";
55+
gzip_types text/plain text/xml text/css
56+
text/comma-separated-values
57+
text/javascript
58+
application/json
59+
application/xml
60+
application/x-javascript
61+
application/javascript
62+
application/atom+xml;
63+
64+
upstream odoo {
65+
server {{ include "adhoc-odoo.serviceNameSuffix" . }}-http:80;
66+
keepalive 32; # Mejora rendimiento para conexiones persistentes
67+
}
68+
69+
{{- $usewebsocket := .Values.odoo.performance.workers | toString | int -}}
70+
{{- if gt $usewebsocket 0 }}
71+
upstream odoochat {
72+
server {{ include "adhoc-odoo.serviceNameSuffix" . }}-websocket:80;
73+
keepalive 32; # Mejora rendimiento para conexiones persistentes
74+
}
75+
{{- end }}
76+
77+
# Used by websocket
78+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#https
79+
map $http_upgrade $connection_upgrade {
80+
default upgrade;
81+
'' close;
82+
}
83+
84+
# Used by static files
85+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#serving-static-files
86+
map $sent_http_content_type $content_type_csp {
87+
default "";
88+
~image/ "default-src 'none'";
89+
}
90+
91+
server {
92+
listen 80 default;
93+
client_max_body_size 1G;
94+
95+
96+
# Prevent browsers from ever sending a plain HTTP request to this domain
97+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#https-hardening
98+
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
99+
100+
# Additional configuration for the session_id cookie.
101+
# The Secure flag ensures it is never transmitted over HTTP
102+
# SameSite=Lax to prevent authenticated CSRF.
103+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#https-hardening
104+
proxy_cookie_flags session_id samesite=lax secure;
105+
106+
# Security
107+
add_header X-Content-Type-Options "nosniff";
108+
add_header X-Frame-Options "SAMEORIGIN";
109+
add_header X-XSS-Protection "1; mode=block";
110+
# Cookies are set to Secure and HttpOnly
111+
proxy_cookie_path / "/; Secure; HttpOnly; SameSite=Lax";
112+
# Additional protection against clickjacking
113+
add_header Content-Security-Policy "frame-ancestors 'self'";
114+
115+
# Redirect requests to odoo backend server
116+
location / {
117+
proxy_pass http://odoo;
118+
# Add Headers for odoo proxy mode
119+
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
120+
proxy_set_header X-Real-IP $remote_addr;
121+
122+
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
123+
proxy_set_header Forwarded "for=$http_x_forwarded_for;proto=$scheme";
124+
125+
proxy_set_header Host $http_host;
126+
proxy_redirect off;
127+
}
128+
129+
{{- if gt $usewebsocket 0 }}
130+
# Redirect longpoll requests to odoo longpolling port (Odoo <= 15.0)
131+
location /longpolling {
132+
proxy_pass http://odoochat;
133+
# Add Headers for odoo proxy mode
134+
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
135+
proxy_set_header X-Real-IP $remote_addr;
136+
137+
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
138+
proxy_set_header Forwarded "for=$http_x_forwarded_for;proto=$scheme";
139+
140+
proxy_set_header Host $http_host;
141+
proxy_redirect off;
142+
# Avoid premature disconections
143+
proxy_read_timeout 86400s;
144+
proxy_send_timeout 86400s;
145+
}
146+
147+
# Redirect websocket requests to odoo gevent port (Odoo >= 16.0)
148+
location /websocket {
149+
proxy_pass http://odoochat;
150+
proxy_http_version 1.1;
151+
proxy_set_header Upgrade $http_upgrade;
152+
proxy_set_header Connection $connection_upgrade;
153+
# Add Headers for odoo proxy mode
154+
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
155+
proxy_set_header X-Real-IP $remote_addr;
156+
157+
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
158+
proxy_set_header Forwarded "for=$http_x_forwarded_for;proto=$scheme";
159+
160+
proxy_set_header Host $http_host;
161+
proxy_redirect off;
162+
# Avoid premature disconections
163+
proxy_read_timeout 86400s;
164+
proxy_send_timeout 86400s;
165+
}
166+
{{- end }}
167+
168+
# Static files are still served by Odoo, because Nginx doesn't have access to
169+
# the Odoo source code. However, they are cached.
170+
location ~ ^/[^/]+/static/.+$ {
171+
proxy_buffering on;
172+
proxy_pass http://odoo;
173+
174+
proxy_cache cache;
175+
proxy_cache_valid 60m;
176+
proxy_cache_valid any 1m;
177+
proxy_cache_revalidate on;
178+
proxy_cache_use_stale error timeout updating;
179+
proxy_cache_background_update on;
180+
proxy_cache_lock on;
181+
182+
expires 24h;
183+
# expires 365d; # TODO: Check if this is a good idea
184+
add_header Cache-Control "public, immutable";
185+
# proxy_cache_valid 200 302 365d; # Cache más largo para respuestas exitosas
186+
# proxy_cache_valid 404 1m; # Cache corto para 404
187+
# add_header X-Cache-Status $upstream_cache_status; # Para debugging
188+
189+
# Security recommendations
190+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#serving-static-files
191+
add_header Content-Security-Policy $content_type_csp;
192+
193+
# Add Headers for odoo proxy mode
194+
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
195+
proxy_set_header X-Real-IP $remote_addr;
196+
197+
proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;
198+
proxy_set_header Forwarded "for=$http_x_forwarded_for;proto=$scheme";
199+
200+
proxy_set_header Host $http_host;
201+
proxy_redirect off;
202+
}
203+
204+
# Filestore storage files are served by Nginx thanks to the X-Accel extension
205+
# Requires the `x_sendfile = True` configuration in Odoo.
206+
# https://www.odoo.com/documentation/18.0/administration/on_premise/deploy.html?highlight=nginx#serving-attachments
207+
location /web/filestore {
208+
internal;
209+
alias /mnt/filestore;
210+
}
211+
}
212+
}
213+
214+
{{- end }}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{{- if .Values.ingress.enableReverseProxy }}
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: {{ include "adhoc-odoo.fullname" . }}-nx
6+
labels:
7+
{{- include "adhoc-odoo.labels" . | nindent 4 }}
8+
app.kubernetes.io/name: {{ .Release.Name }}-nx
9+
annotations:
10+
{{ if .Values.ingress.enableHttps }}
11+
certmanager.k8s.io/disable-auto-restart: "true"
12+
{{- end }}
13+
spec:
14+
replicas: 1 # TODO: Single failure point
15+
selector:
16+
matchLabels:
17+
{{- include "adhoc-odoo.nxselectorLabels" . | nindent 8 }}
18+
strategy:
19+
type: RollingUpdate
20+
revisionHistoryLimit: 2
21+
template:
22+
metadata:
23+
annotations:
24+
{{- if eq .Values.storage.location "fuse" }}
25+
gke-gcsfuse/volumes: "true"
26+
{{- end }}
27+
labels:
28+
{{- include "adhoc-odoo.nxselectorLabels" . | nindent 8 }}
29+
{{- include "adhoc-odoo.adhocLabels" . | nindent 8 }}
30+
adhoc.ar/app-name: "nginx"
31+
spec:
32+
{{- if eq .Values.storage.location "fuse" }}
33+
terminationGracePeriodSeconds: 60
34+
{{- end }}
35+
serviceAccountName: {{ include "adhoc-odoo.serviceAccountName" . }}
36+
containers:
37+
- name: nginx
38+
image: "nginx:1.27-alpine"
39+
ports:
40+
- name: http
41+
containerPort: 80
42+
protocol: TCP
43+
volumeMounts:
44+
{{- if eq .Values.storage.location "fuse" }}
45+
- name: gcs-fuse-csi-ephemeral
46+
{{- if .Values.cloudNativePG.enabled }}
47+
mountPath: /mnt/filestore/odoo
48+
{{- else }}
49+
mountPath: /mnt/filestore/{{ .Release.Name }}
50+
{{- end }}
51+
readOnly: true
52+
{{- end }}
53+
- mountPath: /etc/nginx/nginx.conf
54+
name: nginx-config
55+
subPath: nginx.conf
56+
readOnly: true
57+
volumes:
58+
- name: nginx-config
59+
configMap:
60+
name: {{ include "adhoc-odoo.fullname" . }}-nginx-config
61+
{{- if eq .Values.storage.location "fuse" }}
62+
- name: gcs-fuse-csi-ephemeral
63+
csi:
64+
driver: gcsfuse.csi.storage.gke.io
65+
readOnly: false
66+
volumeAttributes:
67+
bucketName: {{ .Values.storage.aws_bucketname | quote }}
68+
{{/*
69+
Description: Whether your workload should export metrics. This should be set to "false" if you plan on using
70+
71+
Default: true
72+
*/}}
73+
disableMetrics: "true"
74+
{{/*
75+
Directs the CSI driver to skip redundant access control checks for the Cloud Storage bucket, when set to "true".
76+
This reduces the overhead of redundant Kubernetes Service API, Security Token Service, and IAM calls.
77+
When the flag is set, the Cloud Storage FUSE process, running as part of the sidecar container in the Pod,
78+
handles the bucket access control checks
79+
80+
Default: False
81+
*/}}
82+
skipCSIBucketAccessCheck: "true"
83+
gcsfuseLoggingSeverity: warning
84+
mountOptions: "uid=101,gid=101,file-mode=600,dir-mode=700,implicit-dirs=true,o=r,file-cache:enable-parallel-downloads:true,file-cache:parallel-downloads-per-file:4,file-cache:max-parallel-downloads:-1,file-cache:download-chunk-size-mb:3,file-cache:max-size-mb:200,metadata-cache:ttl-secs:-1"
85+
fileCacheCapacity: "200Mi"
86+
{{- end }}
87+
{{- end }}

0 commit comments

Comments
 (0)