I am trying to setup a local server for local network use. The React app works fine and can be access from another computer on the network. The problem is, the API endpoints I created is returning 404 error (but not the Nginx 404). It's being treated like a regular Reactjs app internal page.
Here is my Nginx conf file:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/build;
index index.html index.htm index.nginx-debian.html;
server_name _;
# This is the react app
location / {
try_files $uri /index.html;
}
# This is the restful api
location /api {
proxy_redirect off;
default_type application/json;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Type: application/json;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_intercept_errors on;
proxy_pass http://localhost:5000;
}
}
Here's my React app `package.json:
{
"name": "React APP",
"version": "0.1.0",
"private": true,
"dependencies": {
...
},
"scripts": {
...
},
"devDependencies": {
...
},
"homepage": "."
}
From my localhost machine, I am able to visit http://localhost/ and it shows me my ReactApp just fine, however, http://localhost/api/v1/ and all its endpoints aren't mapping correctly. But if I visit http://localhost:5000, I am able to access my api just fine too.
Can somebody tell me what I did wrong?
The applications run on different ports, 80 for React Application and 5000 for NodeJS server. Have two separate configurations for the two applications under the conf.d folder i.e. react.conf below
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/build;
index index.html index.htm index.nginx-debian.html;
server_name _;
# This is the react app
location / {
try_files $uri /index.html;
}
}
and for the NodeJS endpoint you can have i.e nodejs.conf
server {
listen 80 default_server;
server_name nodeapi.com;
# Redirect all HTTP to HTTPS
location / {
proxy_redirect off;
default_type application/json;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_a dd_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Content-Type: application/json;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_intercept_errors on;
proxy_pass "http://localhost:5000";
}
}
Related
I want to redirect a URL e.g domain.com/api/ to a specific Node.js server, the root URL shows my website. At the moment I use this config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
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:3031/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
but it does not work.
What has gone wrong?
Thanks for help and best regards :)
You fogot closing bracket after location /api section.
Your config working at my machine.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
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:3031/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Also your nodejs backend must handle '/api' requests.
Please note that proxy_pass directive gets argument for backend and optional URI.
That means proxy_pass http://localhost:3031; will get the URI from the user, e.g /api/res.json so final URL for the NODE JS is: http://localhost:3031/api/res.json
But when you provide the URI to the directive itself, it overrides the requested URI in the matching location. e.g location /api and proxy_pass http://localhost:3031/; (note the suffixed slash). so the part /api is replaced by / and final URL is: http://localhost:3031/res.json.
from the NGINX docs:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
So it's important to understand that the part of the requested URI /name/ is replaced by /remote/ and then the rest of the requested URI is added to the final sent URI.
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;
}
I am having trouble accessing my node server externally. Internally, I can access it fine, but I am unable to do so otherwise.
Here is my nginx configuration. I simply want to access my website using only my external IP (for example, 133.21.29.21)
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 2500;
location / {
proxy_pass http://127.0.0.1:3005;
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;
}
}
server code
app.server.listen(3003, "0.0.0.0", () => {
console.log(app.server.address());
});
I am running on port 3003 at the moment. I have tried sever nginx configurations and changing my server code as well (changing port, omitting "0.0.0.0", using "127.0.0.1") but I have not had any luck.
I've been trying to access my server by going to my-external-ip:2500, but i've tried accessing through other ports as well.
I've disable the ufw firewall and still have not had any luck. Curling locally works fine.
What am I doing incorrectly?
I think you are missing a proxy redirect
Take a look at the following example NGINX configuration file, the location / { } is pointing to a Node server on port 9080 and it works by navigating to https:// ... .com
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl on;
ssl_certificate /etc/letsencrypt/live/thedomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/thedomain.com/privkey.pem;
access_log /var/log/nginx/thedomain.access.log;
error_log /var/log/nginx/thedomain.error.log;
server_name _;
root /var/www/html;
index index.html;
gzip on;
gzip_proxied any;
gzip_types text/css text/javascript text/xml text/plain application/javascript application/x-javascript application/json;
location /.well-known/ {
try_files $uri $uri/ =404;
}
location /jenkins {
include /etc/nginx/proxy_params;
proxy_pass http://localhost:8080;
proxy_read_timeout 90s;
proxy_redirect http://localhost:8080 https://www.thedomain.com/jenkins;
}
location /wss/pforex {
include /etc/nginx/proxy_params;
proxy_pass http://localhost:9190;
proxy_http_version 1.1;
proxy_read_timeout 90s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect http://localhost:9190 https://www.thedomain.com/wss/pforex;
}
location / {
include /etc/nginx/proxy_params;
proxy_pass http://localhost:9080;
proxy_read_timeout 90s;
proxy_redirect http://localhost:9080 https://www.thedomain.com;
}
}
Nginx works as a front-end server, which in this case proxies the requests to a node.js server. Therefore you need to set up a Nginx config file for the node.
Create the file yourdomain.com at /etc/nginx/sites-available/:
# the IP(s) on which your node server is running. I chose port 3003.
upstream app_yourdomain {
server 127.0.0.1:3003; # can use localhost as well
keepalive 8;
}
# the Nginx server instance
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
access_log /var/log/nginx/yourdomain.com.log;
# pass the request to the node.js server with the correct headers
# and much more can be added, see Nginx config options
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://app_yourdomain/;
proxy_redirect off;
}
}
Besides you can even omit giving ip to listen method and it will take localhost by default
const app = express();
app.listen(3003, () => {
console.log(app.server.address());
});
If you are accessing the server directly with IP then you need to change
server_name yourdomain.com www.yourdomain.com;
with
server_name _;
I have a node js application running on AWS linux server with ssl. I wanted to implement nginx to the same. I googled it and read that if I implement ssl in nginx then the node application runs on http. So I configured the nginx conf as follows and ran the node js application with normal http server:
listen 443 ssl;
server_name myserver.com;
ssl_certificate myserver.chained.crt;
ssl_certificate_key myserver.key;
ssl_client_certificate myserver.crt;
ssl_verify_client optional;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header VERIFIED $ssl_client_verify;
proxy_set_header DN $ssl_client_s_dn;
proxy_pass http://127.0.0.1:3000;
}
Now the application is running on http as well as https. I want the nginx to be implemented and through ssl and the application to run only on https.
Is my approach right and what am I missing?
I see you have the application running on port 3000, what you will want to do so that it only runs on https is to block all requests on port 3000 to the server (using a firewall or security group rules in aws), and for every request on port 80 you will want to redirect them to the https version (port 443). Something like this:
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
I found the above rule in this answer on serverfault.
upstream app
{
server 127.0.0.1:3000;
}
server
{
listen 80;
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
client_header_buffer_size 64k;
large_client_header_buffers 4 64k;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
location ~ ^/(assets/|images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/|robots.txt|humans.txt|favicon.ico) {
root /var/www/example.com/public/;
access_log off;
expires 24h;
}
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://app$uri$is_args$args;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
I know there are many such questions on stack exchange. But nothing could help to the scenario that I have.
Here is my situation.
I have a webserver running on apache2 listening to the port numbers 7080 and 7081. I have used reverse-proxy method on my server and installed nginx which is listening to the port 80. So now nginx is the front end. I have my wordpress website running on http://www.example.com.
Now I am trying to install node.js app on my server which I could not. It makes sense because port 80 is being used by nginx.
I referred to the following posts on SO
Node.js + Nginx - What now?
Apache and Node.js on the Same Server
I tried the following
upstream example.com/my-app {
server 1**.*.**.**:3010;
}
# the nginx server instance
server {
listen 1**.*.**.**:80;
server_name example.com/my-app;
server_name www.example.com/my-app;
server_name ipv4.example.com/my-app;
access_log off;
# pass the request to the node.js server with the correct headers and much more can be added, see nginx config options
location / {
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-Accel-Internal /internal-nginx-static-location;
proxy_pass http://example.com/my-app;
proxy_redirect off;
}
location /internal-nginx-static-location/ {
alias /var/www/vhosts/example.com/httpdocs/node;
access_log /var/www/vhosts/example.com/httpdocs/node/statistics/logs/proxy_access_ssl_log;
add_header X-Powered-By PleskLin;
internal;
}
}
I wrote the above conf in a file and included it in /etc/nginx/conf.d/xzzeaweae_nginx.conf.
It is not working. but the app is running properly on 1++.+.++.++:3010 though.
My directory structure.
/var/www/vhosts/example.com/httpdocs/
my wordpress website root directory : /var/www/vhosts/example.com/httpdocs/
my nodejs app directory: /var/www/vhosts/example.com/httpdocs/my-nodejsapp-folder/
UPDATE
Here is my reverse proxy config for my apache application
server {
listen +++.+.++.++:80 ;
listen ++.+.+++.++:80 ;
location / {
proxy_pass http://127.0.0.1:7080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Since I have more than one website running on my server,
I have reverse proxy config for every website.
Here it is for one of my website
server {
listen +++.+.++.++:443 ssl;
server_name example.com;
server_name www.example.com;
server_name ipv4.example.com;
ssl_certificate /opt/psa/var/certificates/certaqnxHd2;
ssl_certificate_key /opt/psa/var/certificates/certaqnxHd2;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 128m;
location / { # IPv6 isn't supported in proxy_pass yet.
proxy_pass https://+++.+.++.++:7081;
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-Accel-Internal /internal-nginx-static-location;
access_log off;
}
location /internal-nginx-static-location/ {
alias /var/www/vhosts/example.com/httpdocs/;
access_log /var/www/vhosts/example.com/statistics/logs/proxy_access_ssl_log;
add_header X-Powered-By PleskLin;
internal;
}
}
server {
listen +++.+.++.++:443 ssl;
server_name webmail.example.com;
ssl_certificate /opt/psa/var/certificates/certaqnxHd2;
ssl_certificate_key /opt/psa/var/certificates/certaqnxHd2;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
client_max_body_size 128m;
location / { # IPv6 isn't supported in proxy_pass yet.
proxy_pass https://+++.+.++.++:7081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log /var/www/vhosts/example.com/statistics/logs/webmail_access_ssl_log;
}
}
server {
listen +++.+.++.++:80;
server_name example.com;
server_name www.example.com;
server_name ipv4.example.com;
client_max_body_size 128m;
location / { # IPv6 isn't supported in proxy_pass yet.
proxy_pass http://+++.+.++.++:7080;
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-Accel-Internal /internal-nginx-static-location;
access_log off;
}
location /internal-nginx-static-location/ {
alias /var/www/vhosts/example.com/httpdocs/;
access_log /var/www/vhosts/example.com/statistics/logs/proxy_access_log;
add_header X-Powered-By PleskLin;
internal;
}
}
server {
listen +++.+.++.++:80;
server_name webmail.example.com;
client_max_body_size 128m;
location / { # IPv6 isn't supported in proxy_pass yet.
proxy_pass http://+++.+.++.++:7080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log /var/www/vhosts/example.com/statistics/logs/webmail_access_log;
}
}
Note: sites-available and sites-enabled files are present inside apache2. Not in nginx.
I want my nodejs app to run on example.com/my-nodejsapp-folder/ without any port number.
Any help would be highly appreciated.
http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream
I haven't seen where it says you can use dots and slashes in the upstream name
upstream mynodeapp {
server 1**.*.**.**:3010;
}
then
server {
listen 1**.*.**.**:80;
server_name example.com/my-app;
#...etc.
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# not this.
# proxy_set_header X-Accel-Internal /internal-nginx-static-location;
proxy_pass http://mynodeapp/my-app;
proxy_redirect off;
}
}
Then your node app needs to write a header containing:
X-Accel-Redirect: /internal-nginx-static-location/somefile
There are restrictions, as in, it may not work if you start returning content (e.g. print statements) before returning all headers. It's simpler to first test with only the interesting header.
Example:
# /etc/nginx/conf.d/default.conf
upstream mynodeapp {
server 127.0.0.1:8000;
}
server {
listen 127.0.0.1:80;
location /secret {
alias /tmp/secret;
internal;
}
location /my-app {
proxy_pass http://mynodeapp/my-app;
}
}
And let's try the following:
// /tmp/index.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'X-Accel-Redirect': '/secret/foo'});
res.end('Hello World\n');
}).listen(8000, '127.0.0.1');
And now the command line:
[root#localhost secret]# pwd
/tmp/secret
[root#localhost secret]# echo bar > foo
[root#localhost secret]# curl http://127.0.0.1:80/my-app
bar
[root#localhost secret]# curl http://127.0.0.1:80/secret/foo
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.0.15</center>
</body>
</html>
[root#localhost secret]#
You can take a look into my Nginx config https://github.com/zoonman/ruliq/blob/master/etc/nginx/www.linuxquestions.ru.conf