I have docker swarm setup for a website. The main website is in Angular and specific portion of the website is React application.
The swarm cluster has 3 services for 3 apps. Both Angular and React apps served through Nginx
/api
end points (https://mywebsite.com/api)Primary Nginx config that serves the website and Spring boot and React apps served as upstreams. Below Nginx file shows 3 location blocks for 3 apps.
nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events
{
worker_connections 1024;
}
http
{
upstream springboot
{
server springboot:8081;
}
upstream viewer
{
server viewer;
}
# Redirect all requests to HTTPS server
server
{
listen 80;
server_name mywebsite.com;
# redirects http requests to https
return 301 https://mywebsite.com$request_uri;
}
server
{
listen 443 ssl http2;
server_name mywebsite.com;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /etc/nginx/certs/mywebsite_com.crt;
ssl_certificate_key /etc/nginx/certs/mywebsite_com.key;
ssl_trusted_certificate /etc/nginx/certs/mywebsite_com_truster_chain.crt;
ssl_prefer_server_ciphers on;
location /
{
#### Gzip Settings ####
gzip on;
gzip_min_length 1100;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 5;
#### Serve Angular Application ####
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-store, no-cache, must-revalidate";
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
location /viewer
{
proxy_pass http://viewer;
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-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api
{
proxy_pass http://springboot;
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-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 30m;
include /etc/nginx/conf.d/*.conf;
}
nginx.conf (React)
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
The angular app and /api/
paths work fine. But when I try to go to https://mywebsite.com/viewer path, the JS files are being rendered. Only index.html
file renders and rest of the JS files could not be found and falls back to index.html
which of course fails
Error:
Uncaught SyntaxError: Unexpected token '<'.init-service-worker.js:1
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec. vendors~app.bundle.9…07e3ba0a6ba969.js:1
Uncaught SyntaxError: Unexpected token '<'
As it turns out the issue was with Nginx. Rewriting URL after /viewer/
fixed the issue
rewrite ^/viewer(/.*)$ $1 break;
here is the complete Nginx file
server {
listen 80;
location / {
rewrite ^/viewer(/.*)$ $1 break;
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}