nginx + nodejs configuration - node.js

I have a problem with my current nginx configuration. What I am trying to do is:
For requests without any path, get the index.html (works)
Get existing files directly (works)
If the requested file or path does not physically exist, proxy request to nodejs (404)
I have tried several configurations found here on stackoverflow, but none of them fit my needs.
Here is my current configuration:
# IP which nodejs is running on
upstream app_x {
server 127.0.0.1:3000;
}
# nginx server instance
server {
listen 80;
server_name x.x.x.x;
#access_log /var/log/nginx/x.log;
root /var/www/x/public;
location / {
root /var/www/x/public;
index index.html index.htm index.php;
}
location ^/(.*)$ {
if (-f $request_filename) {
break;
}
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}
}

I think I figured out what you were trying to do. The proper way is to use try_files together with a named location.
Try with the following configuration:
# IP which nodejs is running on
upstream app_x {
server 127.0.0.1:3000;
}
# nginx server instance
server {
listen 80;
server_name x.x.x.x;
#access_log /var/log/nginx/x.log;
location / {
root /var/www/x/public;
index index.html index.htm index.php;
try_files $uri $uri/ #node;
}
location #node {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://app_x;
}
}
Note: When you have an upstream defined you should use that in your proxy_ pass. Also, when proxying, always add the X-Forwarded-For header.

I was wondering that problem is in application path. Please find the following code excerpt from toontuts blog for full configuration of nginx with nodejs, you may find this link
upstream subdomain.your_domain.com {
  server 127.0.0.1:3000;
}
 
server {
  listen 0.0.0.0:80;
  server_name subdomain.your_domain.com;
  access_log /var/log/nginx/subdomain.your_domain.access.log;
  error_log /var/log/nginx/subdomain.your_domain.error.log debug;
 
  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarder-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
 
    proxy_pass http://subdomain.your_domain.com;
    proxy_redirect off;
  }
}

Related

NGINX and Vuejs serving static files

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;
}

Vue and Node configuration nginx

I've hosted my first Vue and Node app but I have a problem. I want to load Vue files on diferent port so there is less stress on node. The problem is that with this current configuration I get this in browser: Cannot GET / even though when in Node router I add route with url / I get something. But I need to load this url from vue router not from express router. Why it loads from express ? This is my configuration file nginx:
server {
listen 80;
listen [::]:80 default_server;
return 301 https://$host$request_uri;
}
server {
# Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name domain.com;
# Use the Letā€™s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:5000;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
location / {
root /var/www/html/Web/dist; // Vue dist folder
}
}
In your nginx config you need to add try_files $uri $uri/ /index.html; to you / location like so. This sends everything to your index.html file.
location / {
root /var/www/html/Web/dist; // Vue dist folder
try_files $uri $uri/ /index.html;
}

404 on POST and GET requests for Node.js app behind NGINX reverse proxy

I have an Ubuntu web server running with this structure:
Nginx reverse proxy localhost:80, which redirects to either '/' (apache server with WordPress site at localhost:8080), which currenly works.
More recently a I've tried to add a Node.js Application at www.site.com/app or, internally, localhost:3000. I am able so serve the HTML and CSS of the node.js webapp, however all internal route calls at 404ing, likely because of the URL addressing of /app/.
IE. Tries to hit /someendpoint and 404s because Node.js is technically running on localhost:3000 (www.site.com/app). Should I be routing arguments like (www.site.com/app/someendpoint)?
The Problem: All POST/GET calls from NODE.JS are 404ing because of my bad understanding of NGINX config. How do I route this GET calls to the actual location of the Node.js server which is (site.com/app/, localhost:3000).
Here is my 'default' config from /etc/nginx/available_sites/.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name www.*site*.name;
location / {
proxy_pass http://127.0.0.1:8080$request_uri;
proxy_buffering on;
proxy_buffers 12 12k;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
#Currenly serving HTML, CSS of site, however node routes 404
location /app/ {
proxy_pass http://localhost:3000/;
}
}
How might I update this NGINX config file to account for node endpoints actively trying to hit the route of my apache site and not the /app real location of the node server?
Any help or ideas would be great, I've been stuck on this issue for a while as part of a personal project.
Thanks!
please remove the try_files statement in the location / block
your location should look like this
.....
location / {
proxy_pass http://localhost:8080;
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;
}
Here is a sample app.js file that may offer you some insight into the matter.
var express = require("express");
var router = require("./lib/routes/index");
var app = express();
var port = 3000;
app.use('/app', router);
app.listen(port, function () {
console.log("Listening on port " + port);
});
As for the nginx configuration, I would recommend something along the lines of the following:
# Sample nginx config with 2 upstream blocks
upstream nodeApp {
server 127.0.0.1:3000;
}
upstream apacheApp {
server 127.0.0.1:8080
}
server {
listen 80;
listen [::]:80;
server_name www.domain.com domain.com;
root /var/www/domain;
location / {
proxy_pass http://apacheApp;
}
location /app {
proxy_pass http://nodeApp;
# OR
# try_files $uri $uri/ #backend;
}
location #backend {
proxy_pass http://nodeApp;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
The key part of this is using an external router in your app.js, then using this line: app.use('/app', router);
You may want to also set up nginx to serve static files instead of relying on express.static(). This would also be easy to do by setting up more location blocks like so:
location /app/public {
try_files $uri $uri/ =404;
}
This should work for your purposes. Don't forget to check your configuration with nginx -t.
For more troubleshooting advice, check out this very similar thread: nginx proxy_pass 404 error, don't understand why
The solution that worked with my 404 issue was to add an extra / after my proxy_pass url.

Subdirectory set as subdomain

I have server with Nginx at front and nodejs which run reactjs application and my application is divided to few parts and I want to each part got own subdomain.
Example:
http://192.168.1.1:9000/part1/ --- > http://sub1.example.com/
http://192.168.1.1:9000/part2/ --- > http://sub2.example.com/
I did something like this:
server {
listen 80;
server_name sub1.example.com;
root html;
index index.html index.htm;
location / {
proxy_pass http://127.0.0.1:9000/part1/;
}}
Server works when i used this config but when I open browser I've got error which telling me about problem with static content.
Server trying take static content from http://127.0.0.1:9000/part1/
Should take from http://127.0.0.1:9000/
Thanks for the help in advance.
Based on your information something like so might work (repeat for both subdomains obviously)
server {
listen 80;
server_name sub1.example.com;
root /home/usr/react/app/build/static;
index index.html index.htm;
location / {
try_files $uri $uri/ #nodejs;
}
location #nodejs {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:9000/part1;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Explained
In this case we are first trying to locate the static files if they exist
try_files $uri $uri/ #nodejs;
If no matching files exist then the request is proxied to the Node.js server on the path /part1
proxy_pass http://nodejs/part1;

How do you serve static files from an nginx server acting as a reverse proxy for a nodejs server?

My current nginx config is this:
upstream nodejs {
server 127.0.0.1:3000;
}
server {
listen 8080;
server_name localhost;
root ~/workspace/test/app;
index index.html;
location / {
proxy_pass http://nodejs;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
I'm very very new to nginx, but at the very least I know that nginx is better than node/express at serving static files. How can I configure the server so that nginx serves the static files?
I solved it using this new configuration:
upstream nodejs {
server localhost:3000;
}
server {
listen 8080;
server_name localhost;
root ~/workspace/test/app;
location / {
try_files $uri #nodejs;
}
location #nodejs {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://nodejs;
proxy_set_header Host $host ;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Thanks to the following Stack Overflow post:
How to serve all existing static files directly with NGINX, but proxy the rest to a backend server.
You'll probably want another location block within your server for the static files.
location /static {
alias /path/to/static/files;
}
This uses the alias directive.
Then you can hit files at localhost:8080/static/some_file.css
P.S. You don't need the root or index that you have set currently.
(root is similar to alias with a slight difference in usage)

Resources