Multiple Benches with Multitenant DNS?

I am trying to install 2 separate benches, each with their own site.

I set up dns multitenant on both of them, however I get a 404 error on site2.com.

DNS resolves to the server.
I used bench config dns_mutlitenant_on for both benches
Sites successfully installed in each bench
I’ve tried bench setup nginx
I’ve tried reloading nginx multiple times.

What am I doing wrong? How is this supposed to work?

Hi:

Have you run bench setup production on both benches?

Yes indeed

Same issue here. With two different ERPNext Server v14 & v15

How can i fix this issue?

I wan´t to install a SSL Wildcard but after i write these command i can´t open the Webinterface from ERPNext and get 404 error:

bench config dns_multitenant on
bench setup nginx
sudo service nginx reload

If i disable DNS Multitenant mode with bench config dns_multitenant off, i can access to my ERPNext Server again.

Regards
Kevin

HI @kevco97 @oguruma:

It’s working well on my side.

Try

bench use yoursite (in each bench)
bench config dns_multitenant on
sudo bench setup production youruser
bench setup nginx
sudo service nginx reload

Hope this helps.

Hello @avc,

thank you for reply.

I have try but same result.

image

Regards
Kevin

So, your problem is accessing from local …Try accessing with your site name, instead ip address
You can add this sitename to hosts file too.

Hello @avc,

i have try from external network but same result.
image

If DNS based multitenancy is on i can´t open ERPNext Interface within local network isn´t it?

I have put DNS Name from ERPNext Site to /etc/hosts but it´s not reachable (Portforwarding configured).

Regards
Kevin

@kevco97:

External access:
Is your domain DNS pointing to the public ip address?

Internal access:
I assume you are trying to access from other computer in the same local network. So, you should configure hosts file in your computer (not in the server), pointing to the LAN ip address of your server …

Hello @avc,

external access:
Yes

Internal access:
okay thank you now i can access via internal network.

But how does it work from external Network with HTTPS?

Regars
Kevin

Try

If you are using wildcard certificate …
bench setup wildcard-ssl yourdomain

@avc i have my own SSL Wildcard certificate (not self signed) and use this manual → Configuring HTTPS
But it doesn´t work.

Checked this?

@avc i have checked thank you. I think the SSL Wildcard is installed cause if i connect to the external DNS Name i see the SSL Wildcard Certificate but get 404 nginx error…

What can i check?

Within local network http & https i can access ERPNext.

Regards
Kevin

Hi @kevco97:

Maybe there isn’t hostname entry on site_config.json or it is wrong …

Try

bench set-config hostname https://erp.yoursite.de
bench restart
bench setup nginx
sudo service nginx reload

Mind that for https traffic you will need port 443 open and redirected to your host …

Hi @avc,

i have try but no luck…

Regards
Kevin

port 443 HTTPS is redirected to host. otherwise I would not get a response from the web server nginx.

If i disable DNS based multitenancy i can access ERPNext external with Port 80 HTTP but not 443 HTTPS.

Regards
Kevin

Please, share your nginx.conf , masking private data.

@avc Here are my nginx config:

upstream frappe-bench-frappe {
server 127.0.0.1:8000 fail_timeout=0;
}

upstream frappe-bench-socketio-server {
server 127.0.0.1:9000 fail_timeout=0;
}

setup maps

map $host $site_name_dxshdfn {
erp.xxx.de erp.xxx.de;
default $host;

}

server blocks

server {

listen 80;
listen [::]:80;


server_name
	erp.xxx.de
	;

root /home/user/frappe-bench/sites;



proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;



add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin";

location /assets {
	try_files $uri =404;
	add_header Cache-Control "max-age=31536000";
}

location ~ ^/protected/(.*) {
	internal;
	try_files /$site_name_dxshdfn/$1 =404;
}

location /socket.io {
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Origin $scheme://$http_host;
	proxy_set_header Host $host;

	proxy_pass http://frappe-bench-socketio-server;
}

location / {

	rewrite ^(.+)/$ $1 permanent;
	rewrite ^(.+)/index\.html$ $1 permanent;
	rewrite ^(.+)\.html$ $1 permanent;

	location ~* ^/files/.*.(htm|html|svg|xml) {
		add_header Content-disposition "attachment";
		try_files /$site_name_dxshdfn/public/$uri @webserver;
	}

	try_files /$site_name_dxshdfn/public/$uri @webserver;
}

location @webserver {
	proxy_http_version 1.1;
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Host $host;
	proxy_set_header X-Use-X-Accel-Redirect True;
	proxy_read_timeout 120;
	proxy_redirect off;

	proxy_pass  http://frappe-bench-frappe;
}

# error pages
error_page 502 /502.html;
location /502.html {
	root /usr/local/lib/python3.10/dist-packages/bench/config/templates;
	internal;
}

access_log  /var/log/nginx/access.log main;
error_log  /var/log/nginx/error.log;

# optimizations
sendfile on;
keepalive_timeout 15;
client_max_body_size 50m;
client_body_buffer_size 16K;
client_header_buffer_size 1k;

# enable gzip compresion
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
	application/atom+xml
	application/javascript
	application/json
	application/rss+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/font-woff
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/xml
	font/opentype
	image/svg+xml
	image/x-icon
	text/css
	text/plain
	text/x-component
	;
	# text/html is always compressed by HttpGzipModule

}

server {

listen 443 ssl;
listen [::]:443 ssl;


server_name
	erp.xxx.de
	;

root /home/user/frappe-bench/sites;



proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;


ssl_certificate      /etc/nginx/conf.d/ssl/certificate_bundle.crt;
ssl_certificate_key  /etc/nginx/conf.d/ssl/private.key;
ssl_session_timeout  5m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;


add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "same-origin, strict-origin-when-cross-origin";

location /assets {
	try_files $uri =404;
	add_header Cache-Control "max-age=31536000";
}

location ~ ^/protected/(.*) {
	internal;
	try_files /$site_name_dxshdfn/$1 =404;
}

location /socket.io {
	proxy_http_version 1.1;
	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Origin $scheme://$http_host;
	proxy_set_header Host $host;

	proxy_pass http://frappe-bench-socketio-server;
}

location / {

	rewrite ^(.+)/$ $1 permanent;
	rewrite ^(.+)/index\.html$ $1 permanent;
	rewrite ^(.+)\.html$ $1 permanent;

	location ~* ^/files/.*.(htm|html|svg|xml) {
		add_header Content-disposition "attachment";
		try_files /$site_name_dxshdfn/public/$uri @webserver;
	}

	try_files /$site_name_dxshdfn/public/$uri @webserver;
}

location @webserver {
	proxy_http_version 1.1;
	proxy_set_header X-Forwarded-For $remote_addr;
	proxy_set_header X-Forwarded-Proto $scheme;
	proxy_set_header X-Frappe-Site-Name $site_name_dxshdfn;
	proxy_set_header Host $host;
	proxy_set_header X-Use-X-Accel-Redirect True;
	proxy_read_timeout 120;
	proxy_redirect off;

	proxy_pass  http://frappe-bench-frappe;
}

# error pages
error_page 502 /502.html;
location /502.html {
	root /usr/local/lib/python3.10/dist-packages/bench/config/templates;
	internal;
}

access_log  /var/log/nginx/access.log main;
error_log  /var/log/nginx/error.log;

# optimizations
sendfile on;
keepalive_timeout 15;
client_max_body_size 50m;
client_body_buffer_size 16K;
client_header_buffer_size 1k;

# enable gzip compresion
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
	application/atom+xml
	application/javascript
	application/json
	application/rss+xml
	application/vnd.ms-fontobject
	application/x-font-ttf
	application/font-woff
	application/x-web-app-manifest+json
	application/xhtml+xml
	application/xml
	font/opentype
	image/svg+xml
	image/x-icon
	text/css
	text/plain
	text/x-component
	;
	# text/html is always compressed by HttpGzipModule

}

http to https redirect

server {
	listen 80;
	server_name
		erp.xxx.de
		;

	return 301 https://$host$request_uri;
}