I'm using this buildpack to serve static files on Heroku with a node + nginx setup. While static assets are served properly, trying to serve content through node results in a 502 Bad Gateway. Node on its own works fine and so does nginx. The problem is when the two need to work together which I guess is because I haven't configured the nginx upstream settings right.
Here's my nginx conf:
worker_processes 1;
error_log /app/nginx/logs/error.log;
daemon off;
events {
worker_connections 1024;
}
http {
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
upstream node_conf {
server 127.0.0.1:<%= ENV['PORT'] %>;
keepalive 64;
}
server {
listen <%= ENV['PORT'] %>;
server_name localhost;
location / {
root html;
index index.html index.htm;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_http_version 1.1;
proxy_pass http://node_conf;
}
location ~* ^.+\.(jpg|gif|png|ico|css|js|html|htm)$ {
root /app;
access_log off;
expires max;
}
location /static {
root /app;
index index.html index.htm;
}
}
}
.
My _static.cfg:
SERVER_TYPE="nginx"
BUILD_WEB_ASSETS="true"
.
My node server:
var app = require( 'express ')()
app.get( '/', function(req, res) { res.send( 'This is from Node.' ) })
app.listen( process.env.PORT )
.
I also have a sample html file in /static to test if nginx works:
<html>This is from nginx.</html>
.
With this config, appname.herokuapp.com should display "This is from Node." but instead I get the 502.
appname.herokuapp.com/static displays "This is from nginx" as it should, so no problems with nginx and static content.
I have tried every combination of values for upstream in nginx server settings but none have worked. What else can I try to make nginx proxy requests to node?
Here's my Heroku Procfile in case it helps: web: bin/start_nginx
I am not really familiar with Heroku, and pretty new to Nginx, but I'll give it a shot: To me it looks like the Nginx-config is saying that Nginx and the node.js app are using the same port (<%= ENV['PORT'] %>).
What you want is Nginx to listen to incoming connections (usually port 80), and have it forward them to the node.js app. Here is an example Nginx config:
# the IP(s) on which your node server is running. I chose port 4000.
upstream xxx.xxx.xxx.xxx { #Your IP adress as seen from the internet
server 127.0.0.1:4000; #Your local node.js process
}
# the nginx server instance
server {
listen 0.0.0.0:80; #Have Nginx listen for all incoming connections on port 80
server_name my-site;
access_log /var/log/nginx/my-site.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://xxx.xxx.xxx.xxx/; #Your IP adress as seen from the internet
proxy_redirect off;
}
}
This config is working for me on a webserver I am hosting in my living-room. Good luck!
Here's a README with information to get nginx and Node.js working together from a project I created a while back. Also included is an example nginx.conf.
As an overview, basically you're just creating sockets with Node then setting nginx to pipe those upstream. I commonly use this when I want to run multiple Node processes and have nginx stand in front of it.
It also includes working with socket.io out of the box, so you can use those to see how to configure your Node instance as well.
Related
I have a basic node server that serves built vuejs application.
The server is running on localhost:3000
Nginx is set to listen on port 80
The app is deployed on the local IP.
nginx config:
upstream nodejs {
server localhost:3000;
}
server {
listen 80;
server_name localhost;
root /mnt/data/app/server/public;
location / {
try_files $uri #nodejs;
}
location #nodejs {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://nodejs;
proxy_set_header Host $http_host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
In index.html all static files are loaded like
css
href="/css/chunk_name.css"
js
src="/js/chunk_name.js"
The issue is that all of those static files are loading over HTTPS
Check the screenshot
If I try to load a single file but replacing HTTPS with HTTP, the file is loaded normally.
I don't know if I am missing something in the config, or it is something else. Any help is appritiated
Config your nginx to serve the static file
location ~ ^/(css|js)/ {
access_log off;
expires 30d;
}
im learning reverse proxy w/ nginx for the first time, and the following isnt working for me
im trying to reroute requests from http://localhost to an api server i have running at http://localhost:8080
server {
listen 80;
location / {
proxy_pass http://localhost:8080;
}
}
when i hit http://localhost, I simply get shown the welcome to nginx splash screen.
if i hit http://localhost:8080, i see my api
I have a node express service running at :8080, which i can hit manually, but shouldn't http://localhost be proxied there too?
When I setup a nginx domain that forwards requests to a node server, it looks like this, for the server_name, you can use localhost as a parameter for accessing it via localhost. You can also pass default_server to make this the default server config.
Note: Only one active config can contain default_server otherwise Nginx will throw errors.
Note: When using default_server, Nginx will catch localhost in that server config. Otherwise you need to specify localhost in the list of server_name's (separated by a space).
server {
# Setup the domain name(s)
server_name example.com;
listen 80 default_server;
# If you would like to gzip your stuff
gzip on;
gzip_min_length 1;
gzip_types *;
# Setup the proxy
# This will forward all requests to the server
# and then it will relay the servers response back to the client
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
}
Found out that adding this to my nginx.conf fixes the issue:
listen [::]:80;
For some reason listen 80; doesn't catch my http://localhost requests.
I tried a lot for this, but not working.
help me any one please..
node is at port 3000 and nginx is at 8080 in localhost
this is node index
var express=require('express'),app=express(),cors =require('cors');
app.use(cors({origin: 'http://127.0.0.1:8080'}));
app.get('/home', (req, res) => {res.send("ok");});
app.listen(3000, '127.0.0.1', function(){console.log('listening on port 3000..');});
this is nginx conf
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 8080;
server_name 127.0.0.1;
location / {
root D:/www;
index index.html index.htm;
}
location /api/ {
proxy_pass http://127.0.0.1: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;
}
}
}
If i use from frontend jQuery
http://127.0.0.1:8080/api/home
it's not working
if i use from frontend jQuery
http://127.0.0.1:3000/home
it's working
this is the error getting in IE,
HTTP404: NOT FOUND - The server has not found anything matching the requested URI (Uniform Resource Identifier).
(XHR)GET - http://127.0.0.1:8080/api/home
server name in nginx conf is not correct. Server names are defined using the server_name directive and determine which server block is used for a given request. They may be defined using exact names, wildcard names, or regular expressions. Replace it with localhost.
For more info read here.
I'm currently running into some configuration problems with NGINX where I keep getting a 502 error instead of NGINX falling back onto a different directory if either the server is down or the directory doesn't exist.
I'm running a Node.js application on port :3000, have SSL set up, and have all HTTP requests redirect to HTTPS. Given the scenario where my node.js application is offline, I wish to send the client to the default NGINX root directory /usr/share/nginx/html index index.htm index.html if possible.
I'm trying to have the nodejs application on port 3000 be shown on / but in the case that the server is down, to fallback on NGINX default directory and display the index.html in there instead. Can anyone help or guide me through this process?
Thank you
Edit: I've tried jfriend00 said in the comments, but now my proxy_pass doesn't seem to work. It would now default to the 500.html regardless whether my server is running or not. I've attached my nginx.conf file, would appreciate any help.
events {
worker_connections 1024;
}
http {
upstream nodejs {
server <<INTERNAL-PRIVATE-IP>>:3000; #3000 is the default port
}
...
server {
listen 80;
server_name <<PUBLIC-IP>>;
return 301 $scheme://<<DOMAIN>>$request_uri;
}
server {
listen 443;
ssl on;
server_name <<DOMAIN>>.com www.<<DOMAIN>>.com;
...
location / {
proxy_pass http://nodejs;
proxy_redirect off;
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 https;
}
error_page 501 502 503 /500.html;
location = /500.html {
root /usr/share/nginx/html;
}
}
}
Adding the error_page works as I did above and it successfully kicks back. Thanks #jfriend00.
If you're deploying it to a live server, you might want to check this out since I had a hard time trying to figure out why my proxy_pass and my NGINX configuration wasn't working on CentOS deployed on EC2. It had nothing to do with the error_page.
my nginx server is actually proxying my node backend (which listens on port 3000) with a simple:
location /api/ {
proxy_pass http://upstream_1;
}
Where upstream_1 is my node cluster defined in nginx.conf (on port 3000).
I'm gonna have to add SSL over http connections, so I have the following question: do I only need to configure nginx to enable ssl? And it will automatically "uncrypt" the request and pass it uncrypted to Node which will be able to handle it normally? Or do I need to configure Nodejs to support ssl as well?
If you're using nginx to handle SSL, then your node server will just be using http.
upstream nodejs {
server 127.0.0.1:4545 max_fails=0;
}
server {
listen 443;
ssl on;
ssl_certificate newlocalhost.crt;
ssl_certificate_key newlocalhost.key;
server_name nodejs.newlocalhost.com;
add_header Strict-Transport-Security max-age=500;
location / {
proxy_pass http://nodejs;
proxy_redirect off;
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 https;
}
}