Can not access meteor app without passing through NginX server?

I have a problem. I can not access my app from outside without passing through NginX web server.

I am doing a custom deploy of meteor on a Linux machine. I am hosting the app at port 3000 and I have made sure that all firewalls are open. When I run netstat -tulpan I can see:

tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 7311/node

But when I browse to the app from a web browser http://addressToMyApp:3000 I can not see the page.

However if I launch a NginX server and forwards the requests from port 80 to 3000 then everything works fine. I want to understand why I must pass through a web server to make it work.

Any suggestions why this does not work?

Where is your linux server? If it is in Azure or AWS you need to open the ports from respective console.

I am hosting on AWS. I have set correct inbound rules to allow ingoing traffic to port 3000. If I run curl and fetch the HTTP headers, I get the following response:

$ curl -I http://ec2-35-158-39-114.eu-central-1.compute.amazonaws.com:3000

HTTP/1.1 302 Found
Location: https://ec2-35-158-39-114.eu-central-1.compute.amazonaws.com/
Access-Control-Allow-Origin: *
Date: Sun, 26 Nov 2017 19:44:19 GMT
Connection: keep-alive

So obviously I get a reponse but not content.

Compare it to when I pass through the NginX server:


curl -I http://ec2-35-158-39-114.eu-central-1.compute.amazonaws.com:80

HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Sun, 26 Nov 2017 20:17:12 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding

So what is the difference when I go directly at port 3000 compared to passing via NginX webserver?

Have you set the inbound rules in both iptables/ufw and the security group the server is in?

1 Like

I think you should this command to test if you are able to reach your port

curl -v telnet://target ip address:desired port number

I tested your command and I obviously can reach the port:

curl -v telnet://ec2-52-29-26-71.eu-central-1.compute.amazonaws.com:3000

But if I browse to this address http://ec2-52-29-26-71.eu-central-1.compute.amazonaws.com:3000/
I see nothing, it just tries to connect.

Have I some incorrect/missing settings in the settings file perhaps?

…

export MONGO_URL=mongodb://localhost:27017/meteor
export NAME=myServ1
export HOST=ec2-52-29-26-71.eu-central-1.compute.amazonaws.com
export PORT=3000
export ROOT_URL=http://ec2-52-29-26-71.eu-central-1.compute.amazonaws.com

I understand nada…

If i create a simple nodejs web-server and listens for port 3000 as below:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.write('Hello World!');
  res.end();
}).listen(3000);

I browse to the server and I get the page correctly! So that means no problems with firewalls or inbound rules. Therefore it must be meteor that does something strange. Is it some setting that I am missing?

The point of having Nginx in the first place is for it to route and load balance traffic between your various webapp instances, so if you have 2 servers running at

localhost:3000
localhost:3001

and your nginx is running on port 80, configured to upstream the above addresses, that means that your users should not be able to access the port 3000 or 3001 instance directly, only through the Nginx gateway at port 80, by default.

Iirc there might be a special config setting for you to override that rule, but I’m not sure, you’d have to do some research.

For sure and that is what I am trying to achieve. But I also want to host some upstream servers on a different server. And I dont see the purpose of having an extra NginX webserver on all upstream servers.

So for example the upstream config could look like:

    upstream tessaupstream {
            ip_hash;
            server localhost:3000;
            server localhost:3001;
            server someotherserver:3000;
            server someotherserver:3001;
    }

But do you mean meteor has some built in logic which prohibits direct access at ports different from 80?

Hmmmm, I don’t believe there’s any hardcoded logic in Meteor about this. Are you sure that you’re not connecting at all to the Meteor app? Try inspecting the dev tools to see if you’re receiving any network response.

Since you’re hosting on AWS, something could be blocking websockets which would prevent the Meteor app from loading.

I think this has something to do with your ROOT_URL.

You posted that when you curl -I to port 3000 you get back:

HTTP/1.1 302 Found
Location: https://ec2-35-158-39-114.eu-central-1.compute.amazonaws.com/

Which is a redirect back to the ROOT_URL without the port.
So it seems the Meteor app is comparing the url it’s accessed on with the ROOT_URL and redirecting?

EDIT:
Looking at Meteor’s code, the only time it should do that is if you’re using the force-ssl package.

You can see that it strips the port off and sends a 302 redirect here:

Are you using the force-ssl package?

1 Like

Oh thank you @coagmano! You really saved my day! I was using obviously using the force-ssl package. I removed it and now it works like a charm! =)

1 Like

Never use force-ssl it doesn’t actually do anything useful, in my experience

My preferred config is for NGINX to do the SSL work and proxy unsecured requests to your servers on localhost or private network

1 Like