Renovation
Search…
Nginx Configuration
A brief guide on how to setup nginx for renovation-cms to use with frappe backend

Basic Configuration

Suppose, you have a site called example.com, with renovation-cms on cms.example.com & frappe backend on frappe.example.com. We will have cms.example.com/api reverse proxied to frappe backend to prevent CORS issue.
The production build of renovation-cms has backend url set to /api
1
upstream frappe-server {
2
server 192.168.0.101;
3
keepalive 16;
4
}
5
​
6
map $http_host $frappe_site_ifisd {
7
"cms.example.com" "frappe.example.com";
8
"" $http_host;
9
}
10
​
11
# LTS-Renovation
12
server {
13
listen 443 ssl;
14
server_name
15
cms.example.com;
16
17
root /home/frappe/www/lts-renovation/dist;
18
19
ssl_certificate /home/frappe/.ssl/example-cert.pem;
20
ssl_certificate_key /home/frappe/.ssl/example-key.pem;
21
​
22
location / {
23
try_files $uri $uri/ /index.html;
24
}
25
26
location /api {
27
rewrite /api/(.*) /$1 break;
28
proxy_pass http://frappe-server;
29
proxy_set_header Host $frappe_site_ifisd1;
30
proxy_set_header Accept application/json;
31
proxy_redirect off;
32
proxy_buffering off;
33
​
34
# include details about the original request
35
proxy_set_header X-Original-Host $http_host;
36
proxy_set_header X-Original-Scheme $scheme;
37
proxy_set_header X-Forwarded-For $remote_addr;
38
​
39
# Websocket support
40
proxy_http_version 1.1;
41
proxy_set_header Upgrade $http_upgrade;
42
proxy_set_header Connection "upgrade";
43
​
44
}
45
46
# optimizations
47
sendfile on;
48
keepalive_timeout 15;
49
client_max_body_size 50m;
50
client_body_buffer_size 16K;
51
client_header_buffer_size 1k;
52
​
53
# enable gzip compresion
54
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
55
gzip on;
56
gzip_http_version 1.1;
57
gzip_comp_level 5;
58
gzip_min_length 256;
59
gzip_proxied any;
60
gzip_vary on;
61
gzip_types
62
application/atom+xml
63
application/javascript
64
application/json
65
application/rss+xml
66
application/vnd.ms-fontobject
67
application/x-font-ttf
68
application/font-woff
69
application/x-web-app-manifest+json
70
application/xhtml+xml
71
application/xml
72
font/opentype
73
image/svg+xml
74
image/x-icon
75
text/css
76
text/plain
77
text/x-component
78
;
79
# text/html is always compressed by HttpGzipModule
80
}
Copied!
Now, let's break it down.

Upstream

Here you can specify the ip address of the VPS where frappe is hosted. If it is hosted on the same VPS, have it replaced with server localhost;
1
upstream frappe-server {
2
server 192.168.0.101;
3
keepalive 16;
4
}
Copied!

The Server Block

You can find common nginx directives inside this. The location block location / is set just like how we set for a SPA, and other nginx optimizations like sendfile and gzip compression has been enabled, along with basic SSL setup.

The API Location Block

One of the important section of this configuration is maybe the /api location block. It forwards all the requests coming in at this endpoint to the frappe server. Every frappe requests, be it downloads, SocketIO or be it anything that concerns frappe, it goes through here. Please follow the comments specified for deeper understanding.
1
location /api {
2
# rewrite will change all /api/<frappe-url> to just /<frappe-url>
3
# when it gets forwarded to the upstream server
4
rewrite /api/(.*) /$1 break;
5
6
# the directive asking nginx to forward the traffic
7
proxy_pass http://frappe-server;
8
9
# This helps in selecting the specific site in a multi-site bench
10
# More on this later
11
proxy_set_header Host $frappe_site_ifisd1;
12
13
# We expect only JSON from frappe-py
14
proxy_set_header Accept application/json;
15
16
# Lets the http-301/302 received from frappe be left intact
17
proxy_redirect off;
18
19
# Forward the response received from the frappe server without buffering it
20
# Locally. This helps in huge file downloads. It forwards the data obtained
21
# from client synchronously
22
proxy_buffering off;
23
​
24
# include details about the original request
25
proxy_set_header X-Original-Host $http_host;
26
proxy_set_header X-Original-Scheme $scheme;
27
proxy_set_header X-Forwarded-For $remote_addr;
28
​
29
# Websocket support (SocketIO)
30
proxy_http_version 1.1;
31
proxy_set_header Upgrade $http_upgrade;
32
proxy_set_header Connection "upgrade";
33
​
34
}
Copied!

Mapping Renovation-CMS Host to Frappe-Site in Multi Site Bench

RENOVATION-CMS HOST
FRAPPE SITE NAME
cms.example-A.com
frappe.example-A.com
cms.example-B.com
frappe.example-B.com
...
...
Take the case of a frappe-bench hosting 10 frappe sites. And there are independent renovation-cms hosts for the same, as shown in the table above. We make use of nginx-mapdirective to help us with this situation.
As we forward all the request coming in at /api, we manually set the Host header that gets forwarded with the value of the variable frappe_site_ifisd1(ignore the random part, it is just to ensure that no nginx variable name conflict happens) which is dependent on $http_host which is the incoming Host header (cms host)
1
location /api {
2
...
3
proxy_set_header Host $frappe_site_ifisd1;
4
...
5
}
Copied!
And look at the map defined at the top of the configuration file.
1
map $http_host $frappe_site_ifisd {
2
"cms.example-A.com" "frappe.example-A.com";
3
"cms.example-B.com" "frappe.example-B.com";
4
"" $http_host;
5
}
Copied!
Please checkout nginx map documentations for more details.

Great! You stayed till the end!

Please reach out to us if you find yourself in trouble with configurations :)
Last modified 1yr ago
Copy link