Web app not loading completely when using Ngnix

Windows 10/11 and Xojo 2023r2 webapp
I have 3 web apps running as a service on a Windows 11 VM. I started with just one app and not using Ngnix but needed to add more apps so I installed Ngnix for Windows. Now all of the apps seem to have a random issue of not loading completely. Sometimes an image will not load, sometimes the datepickers will not popup, sometimes the controls do not move to the correct position. I can refresh the page and it is back to normal. This is happening on all browsers that I test, Chrome, Safari, and Edge. I also have another much larger and highly used webapp on another VM that is not behind Ngnix and it does NOT have any issues. Has anyone else seen this issue? I am not very good with the Ngnix conf files so I may have something wrong there. Ngnix handles the wildcard cert and all apps are on the same VM that Ngnix is running on. These are low usage apps. Thanks for any suggestions.

Can you open the browser’s developer tools to see if it’s throwing an error? Do you see anything wrong in the Networking tab?

2 Likes

I am getting this error in the developer tools. See attached pic. I don’t see anything out of the ordinary in the network tab. Thanks

Here is another screenshot of the XojoDatePicker.render error.

That definitely looks like a bug in that control. Do you mind creating a new Issue for it with a sample project?

Also, what happens if you remove the WebDatePicker? Do you still have issues or does the page loads fine? Not sure what relation could have this problem with deploying your app behind Nginx.

Yes, I will create a sample project. The strange thing is, If I refresh the page then the error goes away and everything works fine.

That’s strange yes, I’ll have to take a look.

@Gary_Smith What does your nginx configuration file look like?

Here is the include for the main app. I can post the Ngnix.conf if you need it.
Thanks

server {
  listen 80;
  server_name www.cbemployment.com;
  rewrite ^ https://cbemployment.com$request_uri redirect;
}
# Redirect http://... to https://...
server {
  listen 80;
  server_name cbemployment.com;
  rewrite ^ https://cbemployment.com$request_uri redirect;
}

upstream cbemployment {
  # Enter the IP address and port number of your server handling this domain
  server 10.0.0.25:64000;
  }

server {
  listen 443 ssl;
  #ssl on;
  ssl_certificate /nginx-1.25.2/ssl/cbemployment.crt;
  ssl_certificate_key /nginx-1.25.2/ssl/cbemployment.key;
  server_name cbemployment.com;
  root html;

  location / {
    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;
    proxy_buffers         4 256k;
    proxy_buffer_size       128k;
    proxy_busy_buffers_size 256k;

    proxy_set_header    Host                 $host;
    proxy_set_header    X-Real-IP            $remote_addr;
    proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto    $scheme;
    proxy_set_header    X-Forwarded-Protocol $scheme;
    proxy_set_header    X-Forwarded-Ssl      off;
    proxy_set_header    X-Url-Scheme         $scheme;
    proxy_set_header    X-Frame-Options      SAMEORIGIN;

    proxy_pass http://cbemployment;
  }

  location ~*  \.(jpg|jpeg|png|gif|ico|css|js|pdf|woff|woff2)(\?.*)?$ {
    expires 365d;
    add_header Cache-Control "public, max-age=315360000";
    access_log off;

    proxy_read_timeout      300;
    proxy_connect_timeout   300;
    proxy_redirect          off;
    proxy_buffers         8 24k;
    proxy_buffer_size       2k;

    proxy_set_header    Host                 $host;
    proxy_set_header    X-Real-IP            $remote_addr;
    proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Proto    $scheme;
    proxy_set_header    X-Forwarded-Protocol $scheme;
    proxy_set_header    X-Forwarded-Ssl      off;
    proxy_set_header    X-Url-Scheme         $scheme;
    proxy_set_header    X-Frame-Options      SAMEORIGIN;

    #proxy_cache            STATIC;
    proxy_cache_valid      200  1d;
    proxy_cache_use_stale  error timeout invalid_header updating
                           http_500 http_502 http_503 http_504;

    proxy_pass http://cbemployment;

  }
}

Here’s another way to do the load balancing that might help.

In this example, there are three instances of the Xojo app running, configured to listen on ports 64000, 64001, and 64002. It uses the “least-connected” load balancing method. (Using nginx as HTTP load balancer)

It’s also configured for rate limiting, but in your case, I don’t think you’ll want to use that. So you might want to comment that out. (NGINX Rate Limiting)

Also, you might want to adjust the log paths. (You can comment them out to use nginx’s defaults.)

It might be worth giving this a try.

Good luck.

limit_req_zone $binary_remote_addr zone=cbemployment:10m rate=10r/s;

upstream cbemployment {
	least_conn;
	server 127.0.0.1:64000;
	server 127.0.0.1:64001;
	server 127.0.0.1:64002;
}

server {
	server_name www.cbemployment.com cbemployment.com;
	listen 80;
	return 301 https://cbemployment.com$request_uri;
}

server {

	limit_req zone=cbemployment burst=20;

	server_name cbemployment.com;
	
	listen 443 ssl http2;
	
	ssl_certificate /nginx-1.25.2/ssl/cbemployment.crt;
	ssl_certificate_key /nginx-1.25.2/ssl/cbemployment.key;	
		
	location / {
		proxy_pass http://cbemployment.com;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $remote_addr;
		proxy_pass_request_headers on;			
	}
	
	access_log /home/ec2-user/cbemployment.com/nginx-logs/nginx-access.log;
	error_log /home/ec2-user/cbemployment.com/nginx-logs/nginx-error.log;	
			
}

Please note that with round-robin or least-connected load balancing, each subsequent client’s request can be potentially distributed to a different server. There is no guarantee that the same client will be always directed to the same server.

You should not use least-connected with UI / Session based Web Apps.

3 Likes

I will give that a try. I did replace the datepickers with the one from Graffiti Suite. It seems to be working fine for now. I will keep an eye on it. Thanks

1 Like