nginx responds with 404 Not Found (Single Page App) - nginx

I have a Single Page Application with regular Browser Router (without hash). Whenever someone navigates through page and hits refresh button nginx tries to find file on this path. So if someone is on mypage.com/about nginx looks for about file and responds with 404 Not Found. How to fix this issue?
I'm thinking about specifying a location with wildcard - mypage.com/* except /api tho, because every backend endpoint in this app starts with api. How to match all paths except one? This is how my config looks like:
upstream frontend {
server frontend:3000;
}
upstream backend {
server backend:8000;
}
server {
listen 80;
location /api {
proxy_pass http://backend;
proxy_set_header Host \$http_host;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
location / {
proxy_pass http://frontend;
proxy_redirect default;
}
}

Why do your proxy requests for frontend app ? I assume that you are using some kind of development server to serve your frontend application. It is better to build your frontend application to static files and serve them as regular static files, without any server except the nginx.
As for your question, if you will build your frontend application into static files you may configure location in nginx like this:
root /var/www/your_site;
location / {
try_files $uri /index.html;
}
where index.html is entrypoint into your application and the root path should be configured to place where it stored.
If you still want to serve frontend application from development server through nginx you may configure nginx to handle errors from upstream and point error page to root of dev server.
In this case following directives should help you:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page

Related

One Next.js instance for two domains - how to redirect?

Let's say I have a business offering two different types of services. I would like to have two domains, eg. example-shop.com and example-rental.com and have one Next.js server instance for both of them (so that they can use common components, styles etc.). How should I configure Next.js or the server (eg. with Nginx) to make it work?
What I've tried:
In my Next.js project, I created the subfolders /pages/shop/ and /pages/rental/. I built the project and run it on the server on port 3000. Then, I set up an Nginx reverse proxy on my server with the following redirects:
server {
listen 80;
server_name example-shop.com;
location / {
proxy_pass http://localhost:3000/shop/;
}
}
server {
listen 80;
server_name example-rental.com;
location / {
proxy_pass http://localhost:3000/rental/;
}
}
The HTML file loads correctly, but all the other files (js, css, images) are also redirected to /shop or /rental and end up with 404. How can I fix this?
My ideas:
only redirect HTML files to localhost:3000/shop or localhost:3000/rental and redirect all the other requests to localhost:3000/ (but how?)
set up Next.js so that all the resource files are stored under a separate directory - then I could do
location /resources {
proxy_pass http://localhost:3000/;
}
... but how?

Download files in remote server using reverse proxy Nginx

I have a server running with Nginx reverse proxy.
We have our application running in another server, which is served using this Nginx proxy. Below is the configuration I have used and its working fine.
location / {
rewrite ^/(.*) /$1 break;
proxy_pass http://10.0.0.121:8000;
}
I would need to download a pdf file in the application machine (10.0.0.121) , which is under /home/ubuntu/app/pdf/data-2021-03-25.pdf.
How could I make the file in application machine downloadable from the proxy server, please help.
Thanks in Advance.
I would simply install another nginx instance on 10.0.0.121 and configure it like this. NON-PROD READY!
server {
listen 8080;
server_name ...;
root /home/ubuntu/app/pdf;
location = /data-2021-03-25.pdf {
try_files $uri $uri/ =404;
}
server {
listen 8090;
location / {
proxy_pass http://localhost:8080;
}
}
}
Not tested but this server will handling the request serving the file. Then you could just use proxy_pass on the other server to proxy the request.
But beside from this option you can use a python, perl, php, java, nodejs, assembly or what ever programming language you want to use to open a http port and serve the file on an incoming request. Its really your choice.
just make sure if you're going for the proxy solution you are sanitizing the requests on your proxy. For example. With a small change in the setup above you could cheat and get any other files from your home/app directory by sending an request like curl -v localhost:8090/pdf/../other/file. So make sure you are using the root(/home/ubuntu/app/pdf/) directive and set a location matching the pdf-file on the proxy-server as well.
That worked in my demo app.

Upload multipart file with nginx as reverse proxy

I am trying to upload files through my web application, but i am keep getting 404 on uploads.
I am useing Nginx as a reverse proxy for .net core web application. Everything worked fine so far, however upload of files for some reason fails.
I am new to nginx, so i might just miss a simple config for this to work.
When i am uploading i am sending post request with content type :
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOge8Ovx1kqih4lfp
Nginx config :
server {
proxy_request_buffering off;
listen 80;
location / {
proxy_pass http://localhost:5000;
client_max_body_size 500m;
}
}
I really cant figure out where to look for an error
Check the user permission of /var/lib/nginx/tmp/client_body

Deploy Create-React-App on Nginx

I'm attempting to deploy my create-react-app SPA on a Digital Ocean droplet with Ubuntu 14.04 and Nginx. Per the static server deployment instructions, I can get it working when I run serve -s build -p 4000, but the app comes down as soon as I close the terminal. It is not clear to me from the create-react-app repo readme how to keep it running forever, similar to something like forever.
Without running serve, I get Nginx's 502 Bad Gateway error.
Nginx Conf
server {
listen 80;
server_name app.mydomain.com;
root /srv/app-name;
index index.html index.htm index.js;
access_log /var/log/nginx/node-app.access.log;
error_log /var/log/nginx/node-app.error.log;
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm|svg)$ {
root /srv/app-name/build;
}
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Access-Control-Allow-Origin *;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
One of the major benefits of React (and Create React App) is that you don't need the overhead of running a Node server (or proxying to it with Nginx); you can serve the static files directly.
From the Deployment documentation you've linked to, Create React App describes what to do:
npm run build creates a build directory with a production build of your app. Set up your favorite HTTP server so that a visitor to your site is served index.html, and requests to static paths like /static/js/main.<hash>.js are served with the contents of the /static/js/main.<hash>.js file.
In your case, run npm run build to create the build/ directory and then make the files available in a location Nginx can access them. Your build is probably best done on your local machine and then you can securely copy the files across to your server (via SCP, SFTP etc). You could run npm run build on your server, but if you do, resist the temptation to directly serve the build/ directory as the next time you run a build, clients could receive an inconsistent set of resources whilst you're building.
Whichever build method you choose, once your build/ directory is on your server, then check its permissions to ensure Nginx can read the files and configure your nginx.conf like so:
server {
listen 80;
server_name app.mydomain.com;
root /srv/app-name;
index index.html;
# Other config you desire (TLS, logging, etc)...
location / {
try_files $uri /index.html;
}
}
This configuration is based upon your files being in /srv/app-name. In short, the try_files directive attempts to load CSS/JS/images etc first and for all other URIs, loads the index.html file in your build, displaying your app.
For note, you should be deploying using HTTPS/SSL to serve it rather than with insecure HTTP on port 80. Certbot provides automatic HTTPS for Nginx with free Let's Encrypt certificates, if the cost or process of obtaining a certificate would otherwise hold you back.
I was hosting NextJS as main app on / and wanted to host CRA on /admin route. Here is what I did:
serve CRA through custom express server
change hostname in package.json
add basename to /admin for react-router
define the following proxy pass:
location / {
proxy_pass http://localhost:3000;
}
location /admin {
proxy_pass http://localhost:3001;
}
location /admin/ {
proxy_pass http://localhost:3001/;
}
Related articles:
CRA Deployment
React-Router
Multiple SPAs
Another StackOverflow question

proxy_pass a symfony application with nginx

I have a symfony application which offers a REST API. On another host (actually docker container) I have a frontend javascript application which is supposed to consume that API. I want to serve them from the same domain and host:
/ - should serve the frontend app
/api/ - should serve the API
I configured nginx like so:
server {
location ~ ^/api/(.*)$ {
proxy_pass http://apihost:8080/$1;
proxy_set_header Host $host;
}
location / {
root /var/www/;
}
}
That works as long as I don't use the debug toolbar and there is no exception. In that case, the URLs (images, css, js) in the page don't contain the /api/ prefix causing 404s.
How can I configure either symfony or nginx to prepend that prefix to the urls?

Resources