Static files are served locally but not through nginx - node.js

I'm running a node.js API on a VPS, which is served by nginx on Ubuntu 13.04.
I'm using restify and serving static files like this:
server.get(
/\/static\/?.*/,
restify.serveStatic({
directory: __dirname // => /home/misha/rxviz-api
})
);
Here is the relevant bits from nginx config:
server {
listen 80;
server_name api.rxviz.com;
location / {
proxy_pass http://localhost:4010/;
}
}
(full config is here)
When running:
curl http://localhost:4010/static/.well-known/acme-challenge/test.json
on the VPS, I get the contents of test.json.
However, when navigating to:
http://api.rxviz.com/static/.well-known/acme-challenge/test.json
in a browser, I get 404.
nginx error logs show that /opt/nginx/html/static/.well-known/acme-challenge/test.json not found.
Why does nginx trying to access test.json in /opt/nginx/html rather than /home/misha/rxviz-api?
Few more points:
static directory permissions are drwxrwxr-x
I can access http://api.rxviz.com/ in the browser successfully

It's hard for me to be sure, as I can't test it, BUT..
I think you have a problem with the nginx settings:
location /static/ {
alias /home/misha/rxviz-api/static/;
}
the /static is appended to the alias including the location part, so it's searches for /home/misha/rxviz-api/static/static
This is going to return 404 since there is no static/ within static/
try to fix to:
location /static/ {
alias /home/misha/rxviz-api/;
}
....
...
and also I wanted just to mention.
It's seems like your node server (using restify) is serving the content as you wanted (127.0.0.1:4010/static/... works as you say),
BUT note that nginx is anyway not redirecting any of the /static calls into your node, so your node restify is unused.
why?
This section:
location /static/ {
alias /home/misha/rxviz-api/static/;
}
tells nginx to NOT redirect those /static calls into your node service, and instead try to find and serve the file from the local path.
so if you want to use the restify... just remove this entire location /static part, and your node will serve those files too.

Related

NGINX: Proxy only upstream calls

I hope this question is not too simple to include here. Any advice would be appreciated.
I have a situation where I am using a single url to host multiple different angular projects on nginx. I use path extensions to differentiate between the sites. It looks something like this:
server {
listen 443 http2 ssl;
#listen [::]:80;
server_name site.local;
. . .
root /usr/share/nginx/html/. . .;
. . .
location /site1 {
alias /usr/share/nginx/html/. . .;
. . .
location /site2 {
alias /usr/share/nginx/html/ . . .;
. . .
What complicates this is that site1 and site2 share an upstream api on tomcat. When these api calls are made, however, "site1" or "site2" gets inserted into the call.
I'm quite ignorant as to how proxying works on nginx, so attempting to use a proxy_path in the location blocks in the simplest way results in calls to nginx (for html files etc.) are also proxied, making the site inaccessible.
Is there a way to set it up such that only upstream calls get rewrote/proxied?
Any advice would be greatly appreciated.
I'm going to make a few assumptions about your build and correct me if I am wrong. but I see two options to resolve this considering they share the same API you can make the changes in the angular build Or in NGINX. Assuming your nginx server name is example.com it contains a location for /site1 and /site2
example.com/site1
example.com/site2
Options 1 Angular
if the URL is public you can simply route calls by setting the environment.ts inside the environments folder.
export const environment = {
production: false,
apiUrl: 'https://example.com/api',
}
You may need to deploy a production environment.ts and a test environment.ts with their respective apiUrl's for each build. But assuming they share the same API all you would need is a nginx location to said upstream API
location /api/ {
proxy_pass upstream_api;
}
Option 2 NGINX
Let's assume you don't want the full API URL in the environment.ts what is the Nginx option. I don't like this method because it's not as D.R.Y and you find yourself writing two nested locations.
location /site1 {
alias /usr/share/nginx/html/. . .;
#any other settings...
#SUB LOCATION TO API
location /site1/api/ {
rewrite /site1/(.*) /$1 break;
proxy_pass upstream_api;
#any other settings...
}
}
location /site2 {
alias /usr/share/nginx/html/. . .;
#any other settings...
#SUB LOCATION TO API
location /site2/api/ {
rewrite /site2/(.*) /$1 break;
proxy_pass upstream_api;
#any other settings...
}
}
Let's break this down.
the first location /site1 will qualify and url using site1 thus your SPA application can route to any url. But when making a request to an API it will seek the 2nd qualifier in the nested location /site1/api/ we use /site1/api so that Nginx knows that /api is not outside of the location.
Lastly rewrite /site1/(.*) /$1 break; will remove the site1 and send the rest of the url upstream to resolve your problem.
Hope this helps.

Nginx configuration to serve a dynamic files within a root folder

I have a mern stack application with the following structure
.app/
--client folder
-server.js
-storage folder
The application works just fine in local, though when i have deployed to amazone (ec2) and configured pm2 and nginx everything works fine but the only issue that images saved in my storage folder do not seems to be served.
Static images in the build folder are displayed normaly but when the user uplaods his profile image for example which saved in the storage, the image gets saved but not displayed.
My nginx config are very common:
root /path/tp/build;
location / {
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://localhost:8080;
//other default configs;
}
I was trying to play with config to make it works but wasn't successfull.
I also added a location in the nginx config for the storage folder
location /storage/ {
root /path/to/storage/;
try_files $uri /;
}
I would appreciate any help, thank you.

How to set proxy pass for react app on nginx?

My react app has got different routes to consume different functionalities
e.x.
localhost:3000,
localhost:3000/Dashboard,
localhost:3000/Hub,
localhost:3000/Person
etc....
I wanted to configure the react app routes in the nginx in the production environment. What I have actually done so far in the nginx configuration at production env is,
server_name api.vesta-project.net;
location /vqcc {
proxy_pass http://localhost:3000/;
}
My problem here is with the current settings, the homepage works well when I say "api.vesta-project.net/vqcc". Whereas, when I click a button that navigates to /Dashboard. I get 404 error as it does not append "vqcc" to the path in the react app internally thus it becomes like api.vesta-project.net/Dashboard" when inspecting the request which is wrong per nginx conf. So I need a solution whenever the client make a request, it should append "vqcc" to the path so that it will become a valid url as per nginx routes.
e.x when client request for api.vesta-project.net/Dashboard, it should become
api.vesta-project.net/vqcc/Dashboard
Pls help me if I can handle this at nginx or package.json without being changing any routes in the react app internally
You can try rewriting the uri in catch-all location.
location / {
rewrite /(.*) /vqcc/$1;
}
location /vqcc{
proxy_pass http://localhost:3000/;
}

How can I configure my Nginx file to correctly display my React app?

I've got my build folder on my server and I assume I've correctly configured nginx to be able to see it (I copied the config from Deploy Create-React-App on Nginx), but I still get a 404 page when I try to navigate to it. Is my nginx file just not configured right? I can't figure out what could be causing this problem.
I've tried following Deploy Create-React-App on Nginx exactly, changing things to match my own server name etc. when appropriate.
This is the section I've added to my config file:
server {
listen 80;
server_name xxx.net www.xxx.net;
root /var/www/xxx.net/html/build;
index index.html;
location /news {
try_files $uri /index.html;
}
}

nginx proxy to remote node.js express app in subdirectory

I am completely stuck with a situation where I want to have several node applications on one server. I get this working fine by having the applications running on different ports. I can access the applications by putting in the ip address with port.
I would like to proxy the applications from my nginx server by using different sub-directories like so:
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001;
}
location /app2 {
proxy_pass http://10.131.6.181:3002;
}
Doing this I had to move the all the express routes to /app1 for application1. This works but now I am stuck with the static files.
I can now access the application with http://10.131.6.181:3001/app1 which is great, but via http://my.domain/app1 the static files are not loaded.
The static files can be accessed directly http://10.131.6.181:3001/css but not via the proxy http://my.domain/css
Ideally I would like to have the applications on different ports without the sub-directory in the express routes but only sub-directories in the proxy. I tried to put my head through the wall for the last 5 hours but didn't achieve anything.
Now I would happy if can at least get the static files via the nginx proxy.
An updated answer for anyone who needs:
instead of
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
use
location /app1/ {
proxy_pass http://10.131.6.181:3001/;
}
or if on local
location /app1/ {
proxy_pass http://localhost:3000/;
}
This is the correct way and this way you will not need to modify express. Express will receive only the part after /app1/
I finally worked it out after a google surge.
I added the directories to the nginx proxy_pass
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
location /app2 {
proxy_pass http://10.131.6.181:3002/app2;
}
And I had to change the express applications to use the subdirectory
app.use('/app1', express.static(path.join(__dirname, 'public')));
app.use('/app1'', require('./routes'));
In the router I had to prefix all the redirects.
router.get('/logout', function (req, res) {
req.logout();
res.redirect('/app1/login');
});
The static files are called like so from html
<link rel="stylesheet" href="/app1/css/style.css"/>
A bit of a pain to change all the redirects and static url. I am sure there is a smarter way by setting a global variable in my node-express app. If anybody knows an easier way please post...

Resources