Reverse proxy with nginx + app on Galaxy

Hi @illustreets, thanks for your reply. In my case the meteor app is on the base domain (eg. https://mypage.com/) and the blog is ‘1 level’ down under /i/ (eg. https://mypage.com/i/blog) - So I set the ROOT_URL to the URL the base domain:


"ROOT_URL": "https://mypage.com"

This setup worked well on a different hosting (Modulus.io / Xervo.io) but does not work on Galaxy for some reason. Blog still works fine and switching the proxy_pass back to a xervo URL results in the app loading well again. Using a galaxy url fails though

And you get the 502 error even though the config in Nginx is:

location / {
    proxy_pass http://mypage.com; # meteor app
}

If that’s the case, then I’m not sure what to do next, given that I don’t have your .conf file. It might very well be because of another proxy in front of your app (on Galaxy). I would say, as a Galaxy customer, you should raise a ticket. They are quite fast and very helpful.

I hope you get to solve the issue.

Yes I contacted them - waiting for a reply :slight_smile:

No, my Nginx config would point to the Galaxy URL i.e.

 location / {
    proxy_pass https://mypage.eu.meteorapp.com/; # meteor app
}

 location /i/ {
    proxy_pass https://myblogserver.com; # server URL serving PHP based CMS
}

Since mypage.com is the address of the reverse proxy server (which decides whether to load content from meteor app, or the blog based on the URL)

Sorry, obviously.

Well, I guess it is worth waiting for the guys at Galaxy to respond.

1 Like

@illustreets @paul_bo - Galaxy support came back to me with a solution that worked for me. I needed to add the option proxy_ssl_server_name on; to my nginx config (as documented at http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_server_name)

Quoting Galaxy support: “Galaxy does not have a single IP per domain, so it can only know which certificate to use in the TLS handshake if it knows which domain will be requested. As the SSL handshake happens before the HTTP request, the Host header is not available and SNI (the TLS feature enabled by that flag) acts as a complement for that purpose.”

So my config now looks something like this:

    location / {
        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 Host $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass https://mypage.eu.meteorapp.com;
        proxy_redirect off;

        # Handle Web Socket connections
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_ssl_server_name on;
    }
2 Likes

Thank you for getting back with the solution. I’m sure this will be useful to many

1 Like

We also stuck Nginx in front of our Galaxy instances, but Nginx cached the Galaxy IP for our instance and then it wouldn’t load up till we restarted nginx. Did you ever run into this issue? How are people getting around it?

I’ve had instances where I need to restart nginx because the application wouldn’t load up through nginx and would load up fine when accessed directly via the galaxy URL. TBH I’m not fully active on the project anymore so I didn’t really look into what caused it. So it could very likely be the case you are mentioning. How did you confirm that nginx was caching the galaxy IP please?

Tried the same, not working, Please check

What happens if you curl the localhost on port 3000? is meteor resolvable? if so you just forward an upstream in nginx it works easy as pie

Meteor is working fine on the port but not on the port I want.

location ~ ^/group {
rewrite ^/group/(.*) /$1 break;
proxy_pass http://group:3001; // Working on 3001, separately but now on 3003
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection ‘Upgrade’;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

So what’s the problem here if it’s working fine? You want it to run on 3003 just start meteor with PORT=3003 in the shell vars use export PORT=3003 and then start her up

I want to use NGINX as API Gateway.

There are 2 apps which I am running as a Micro Services

1st one is running on port 3000, working fine (when checking at localhost:3000)
2nd one is running at 3001, this is also working fine when checking at localhost:3001

Now, the problem comes when I tried to access this why a new port which is configured via NGINX i.e 3003. (Please check all the configuration here: Using NGINX as API Gateway, Frontend Not loading)

Now the application running on localhost:3003 is working fine (which is the one running on localhost:3000) but when I navigate through NGINX then the frontend is not loading.

Please check the post, for all the configuration ( Using NGINX as API Gateway, Frontend Not loading)

Ah ok, Nginx will be listening on ports 80 and 443 because that’s the standard web browser ports for HTTP/S traffic and what all browsers are using. That’s why you dont have to type in meteor.com:80 to visit meteor. Port 80 is assumed.

When you view localhost:3000 you will see the meteor app that is running on port 3000 and when you view :3001 you will see the meteor that is working on there - you are not seeing Nginx. To verify this run a curl -I http://localhost:3000 and check headers. If you don’t see a nginx signature or alternatively if you don’t have terminal you could of determined this from the browser alone by triggering a 404 or error. If you don’t see the nginx error screen it’s direct to meteor still. Nginx will reverse proxy this to the listening port - which by default will be 80/443 depending if you have ssl setup locally

So you’ll find your Nginx is probably already working happily on http://localhost to make it work on http://localhost:3003 you’ll need to change your listen directive to listen on port 3003 and you restart nginx.

For example you must find and change

server {
    listen      80;

to

server {
    listen      3003;

But it’s best to just run on port 80 because that’s mean you don’t have to type in the port and will avoid issues with users trying to access it and misunderstanding how to type in a port. It’s more userfriendly on the default.

curl -I localhost when Nginx is actually forwarding will return something like the following, note the server line. The first example is autoforwarding to SSL because that’s how I run it.

$ curl -I localhost
HTTP/1.1 301 Moved Permanently
Server: nginx/1.20.1
Date: Tue, 31 May 2022 08:06:05 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://localhost/

Below this is when you are direct to meteor port 3001 notice no server header:

$ curl -I http://localhost:3000
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
vary: Accept-Encoding
date: Tue, 31 May 2022 08:05:51 GMT
connection: keep-alive
keep-alive: timeout=5

Manual page (always RTM FTW):

http://nginx.org/en/docs/http/request_processing.html

I have not used port 80. I just want it to be configured on local machine first

below is the code I have used, please check

worker_processes 4;

events {
    worker_connections 1024;
}


http{
    server{
        listen 3003;

        location / {
            proxy_pass http://main_web:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'Upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        location ~ ^/group {
            rewrite ^/group/(.*) /$1 break;
            proxy_pass http://group:3001;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'Upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

    }
}

Make sure your proxy pass directives are resolving because they are set to main_web and group - are you sure those resolve? You should check that, or just use the IP or localhost to ensure that it can be resolved. That would be the first thing I would check here.

Yes, they are resolved, I get the title of the page, I want to render but not the content

What do the logs say? Any errors in consoles? What happens if you use the IP instead?

Logs::

nginx-proxy_1  | 172.19.0.1 - - [31/May/2022:10:24:10 +0000] "GET /524ea151167f0aa67862fb6b681b532466a7bc87.css?meteor_css_resource=true HTTP/1.1" 200 78 "http://localhost:3003/groups" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
nginx-proxy_1  | 172.19.0.1 - - [31/May/2022:10:24:10 +0000] "GET /9503405409bb540c2fde020180d23fadce7113ec.js?meteor_js_resource=true HTTP/1.1" 404 49 "http://localhost:3003/groups" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
nginx-proxy_1  | 172.19.0.1 - - [31/May/2022:10:24:10 +0000] "GET /9503405409bb540c2fde020180d23fadce7113ec.js?meteor_js_resource=true HTTP/1.1" 404 49 "http://localhost:3003/groups" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"

Not working when used IP too i.e 127.0.0.1

Remove the rewrite from your nginx location block and just route /group and see what happens, looks like it has routed kind of but if you’re getting a blank page then the rewrite must be screwing with the meteor setup because the core needs to request it’s files and the rewrite is getting in the way so probably not compatible to do it this way.