Exactly what the title says, but for context:
I do have access to the upstream resource, and I am allowing all origins there.
When my NGINX conf does not include the directive add_header 'Access-Control-Allow-Origin' '*';
my browser tells me:
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
When I do include the above directive, my browser tells me
Access to XMLHttpRequest at 'http://localhost/{{ upstream_path_redacted }}' from origin 'http://localhost:8080' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:8080, *', but only one is allowed.
The second issue makes sense. As I stated, I am allowing all origins on the upstream server. I therefore don't understand why removing the directive causes the first issue.
My nginx.conf
:
events {}
http {
upstream my-upstream-service {
server my-upstream-service:5000;
}
server {
listen 80 default_server;
location / {
# this works fine. just included as base case.
return 200 'ok';
add_header Content-Type text/plain;
add_header 'Access-Control-Allow-Origin' '*';
}
location /upstream {
# removing the next uncommented line results in 'missing header' issue.
# keeping it results in 'multiple header' issue.
add_header 'Access-Control-Allow-Origin' '*';
proxy_pass http://my-upstream-service;
}
}
}
What's confusing me even more: upon viewing the logs of both the my-upstream-server
, and the nginx
logs, the request is successfully being made to the upstream server???
All of my digging has brought me to solutions solving either one of the aforementioned issues, but not what to do when both are occuring. I'm stumped.
Further context if necessary:
I am using docker-compose
to deploy these services (inc. the front-end, which is a Vue SPA).
The my-upstream-service
is a Flask
webserver, using Flask-Cors.
Here's the docker-compose.yml
---
version: '3.8'
networks:
gateway-service:
driver: bridge
services:
my-upstream-service:
build:
context: path/to/context/
dockerfile: path/to/dockerfile
ports:
- "5000:5000"
expose:
- "5000"
networks:
- gateway-service
frontend:
build:
context: /path/to/context
dockerfile: /path/to/dockerfile
ports:
- "8080:8080"
expose:
- "8080"
depends_on:
- gateway
networks:
- gateway-service
gateway:
image: nginx:1.19.8-alpine
volumes:
# this is where my nginx.conf lives.
- ./nginx/:/etc/nginx/
ports:
- "80:80"
environment:
- NGINX_PORT=80
depends_on:
- my-upstream-service
networks:
- gateway-service
I'm not sure why I got downvoted without any feedback regarding my question or why I was being downvoted.
Anyways, after a few hours of keyboard mashing I got something to work.
Essentially, also serving the Vue app behind the NGINX reverse proxy, while it created more issues, solved the issue described above in the long run.
I had to add additional configuration to both my Vue app and my NGINX conf to enable all of Vue's development capabilities to work completely. Here's a minimal version of the final NGINX conf:
events {}
http {
upstream upstream-service {
server upstream-service:5000;
}
upstream front-end {
server front-end:8080;
}
server {
listen 80 default_server;
location / {
proxy_pass http://front-end;
proxy_set_header Host localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host localhost;
proxy_set_header X-Forwarded-Server localhost;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_redirect off;
proxy_connect_timeout 90s;
proxy_read_timeout 90s;
proxy_send_timeout 90s;
}
location /sockjs-node {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://front-end;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /upstream {
proxy_pass http://upstream-service;
}
}
}
I also had to add to my vue.config.js
:
module.exports = {
devServer: {
disableHostCheck: true
}
}