I wanna use nginx to run my node.js application. I created a build of the application and inside my nginx.conf I set the root to point to the location of the build folder. This worked and my application ran successfully on nginx.
Now I'm wondering if I could serve dynamic content directly through nginx. Like how I would get the app running with npm start can I do something similar with nginx instead of using the build(static) files?
You need a reverse proxy.
In your application. Configure your server to run on an internal port. For example 3000.
Then configure nginx to proxy connections to your app. Here's a simple nginx configuration to do just that:
root /path/to/app/build;
# Handle static content
location ^~ /static {
try_files $uri $uri/ =404;
}
# Handle dynamic content
location / {
proxy_pass http://127.0.0.1:3000;
}
Or, if you prefer, you can invert the URL scheme to default to static files:
root /path/to/app/build;
# Handle dynamic content
location ^~ /api {
proxy_pass http://127.0.0.1:3000;
}
# Handle static content
location / {
try_files $uri $uri/ =404;
}
Why do something like this?
There are several reasons to use an nginx front-end instead of setting your server to serve directly on port 80.
Nginx can server static content much faster than Express.static or other node static server.
Nginx can act as a load-balancer when you want to scale your server.
Nginx has been battle-tested on the internet so most security issues has been fixed or is well known. In comparison, express or http.server are just libraries and you are the person responsible for your application's security.
Nginx is a bit faster at serving HTTPS compared to node. So you can develop a plain-old HTTP server in node and let nginx handle encryption.
Related
After coding my first website on React, I want to host it on a raspberry pi using nginx.
I have checked website is ok by npm start:
I then built it to create static files using npm run build to create the following files in ~/Documents/myWebsite1/build:
asset-manifest.json css favicon.ico files images index.html js manifest.json resumeData.json robots.txt static
After this I installed nginx, deleted default in both /etc/nginx/sites-available and /etc/nginx/sites-enabled then added the following file in /etc/nginx/sites-available:
server {
listen 80;
server_name localhost;
root ~/Documents/myWebsite1/build;
index index.html index.htm;
location / {
try_files $uri /index.html =404;
}}
nginx -t confirms syntax is ok.
nginx -T confirms only this server block is running.
When I go to my IP address, the page just reads 404 Not Found.
I have checked the logs using sudo tail -n 20 /var/log/nginx/error.log which return:
2022/01/10 18:01:25 [notice] 15929#15929: signal process started
Any ideas as to what I might be doing wrong?
Cheers,
Will
Nginx was trying to access the directory ~/Documents/myWebsite1/build but ~ is only a shell shortcut. Changing to an absolute path fixed it right away :)
I am running on ubuntu. I have nginx running on my computer. I get the welcome page for nginx when I go to the my ip address in the browser but I can't see my react app. I just get a 404 error that says nginx on it. My app is a react app built with create-react app. I made the build with npm run build. I created a site in site-available with nano. which looks like
server {
server_name 192.168.43.177;
root home/a/Documents/d/dapp1/mainDapp/client/build/;
index index.html;
location / {
try_files $uri /index.html =404;
}
}
at first I ran
sudo ln -s /etc/nginx/sites-available/sdft /etc/nginx/sites-enabled/sdft
That brings up 404 error page in the browser that says nginx on it. I then ran this command
sudo ln -s /etc/nginx/sites-available/sdft.nginx /etc/nginx/sites-enabled/sdft.nginx
that bring up "This site can’t be reached" when I go to the ip address in my browser
and every time I edit a file I restart the server but there is no mention of nginx on the error page.
systemctl restart nginx
Please help me.
I am adding an another answer.
You want to navigate to the IP (192.168.43.177). Webservers listen to port 80 (by default).
I get the welcome page for nginx when I go to the my ip address.... is it like this?
If yes nginx is working properly. Goto /etc/nginx/sites-available/default and see what is the path of the root.
In the example above, path is /var/www/html. You should copy your build to this path, i.e. your index.html must be here.
You dont have to change anything in the default.
Running on the belief that you have already loaded the index.html directly with your browser ...
I believe nginx looks for .conf files.
Please try renaming your /etc/nginx/sites-available/sdft.nginx to sdft.conf
Then please try setting your symlink to
ln -s /etc/nginx/sites-available/sdft.conf /etc/nginx/sites-enabled/sdft.conf
If your issue remains unresolved then please try
server {
server_name 192.168.43.177;
root home/a/Documents/d/dapp1/mainDapp/client/build/;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Noting the change in from index.html to $uri/ location.
Please also validate your system is listening for port 80 and no other services are competing.
Due to reputation limits I can not ask you questions.
Firstly check if all configuration for nginx is passing with:
sudo nginx -t
Is it okay?
sudo ln -s /etc/nginx/sites-available/**sdft** /etc/nginx/sites-enabled/**sdft**
These filename must match.
and also try adding listen 80;, so that it knows what port to listen to.
server {
listen 80; # add this
server_name 192.168.43.177;
root home/a/Documents/d/dapp1/mainDapp/client/build/;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
I'm trying to set up a microservices architecture for a personal blog.
The idea is to have an NGINX container serving up a static gatsby site, and to redirect to other services. For example, I'd like to have a react app at /todos, and an api for that todo app at /todos_api.
My current folder structure is like this:
docker-compose.yml
gatsby_blog
(contains a build folder)
nginx
default.conf (this is my main nginx entry)
portfolio
todos
todo_client
nginx
default.conf (this is just for serving the react app)
todo_api
My docker-compose file looks like this:
version: "3"
services:
gatsby:
restart: always
build:
dockerfile: Dockerfile
context: ./gatsby_blog
ports:
- "80:80"
todoclient:
build:
dockerfile: Dockerfile
context: ./portfolio/todos/todo_client
My main Gatsby nginx file looks like this:
upstream todoclient {
server todoclient:3000;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /todos {
rewrite /todos/(.*) /$1 break;
proxy_pass http://todoclient;
}
}
and my React nginx config is like this:
server {
listen 3000;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
The issue I'm pretty certain is with my nginx configs. When I go to localhost I'm met with the gatsby app, but if I go to /todos I get an nginx error. I can see that the request is passed on to the todoclient container correctly, but the error returned is:
open() "/usr/share/nginx/html/todos" failed (2: No such file or directory
If anyone can see where I'm going wrong with the nginx configs I'd really appreciate it. I can post my Dockerfiles too if needed.
Thanks
EDIT
I've managed to get the proxy working now, but the issue is that the todos app cant find its static files. They're in the correct place in the container, and the container works in isolation, so the issue is to do with docker-compose and the nginx proxying.
Done it for angular. The nginx file should replace the file in /etc/nginx/nginx.conf. And place the todos folder - assuming that has the static pages - in /usr/share/nginx/html. You can try one service at a time
http {
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;
location /todos {
alias /usr/share/nginx/html/todos/;
absolute_redirect off;
rewrite ^(.+)/todos/+$ $1 permanent;
rewrite ^(.+)/todos/index.html$ $1 permanent;
try_files $uri$args $uri$args/ $uri/ /todos/index.html;
}
}
}
I've got React app.
It works well on local machine (app + prerender-spa-plugin). I run it with command http-server into ./build package
However thing go wrong on server - it acts like if I launch it with serve-s command.
There is docker with nginx image on server.
I tried to reconfigure nginx the way that it uses different index.html for different URLs, but fail again
Do the problem with routing to directories that keeps static images?
How it could be resolved? or where I could find information about it?
You have to create virtual host on nginx server and point it to build folder of the app. Don't forget to run npm run build.
Simple nginx config
server {
listen 80;
listen [::]:80;
root /var/www/reactjsapp/build;
index index.html index.htm;
server_name reactjsapp.com;
location / {
try_files $uri /index.html;
}
location ~ /\.ht {
deny all;
}
}
I decided it.
My config
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
From official documentation:"It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”."
https://i.stack.imgur.com/PusBE.png
This should be my last question regarding FastCGI and NGINX (I've asked way too many already), but I had a question regarding running C FastCGI scripts on a web server, specifically NGINX. So right now this is how my nginx.conf file looks like:
user nobody nobody;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name localhost;
location / {
root /nginx/html;
index index.html index.htm new.html;
autoindex on;
fastcgi_pass 127.0.0.1:8000;
}
}
}
I have a simple C FastCGI script that prints out Hello World. I know that in order to run this script, I first have to compile the C script which would result in a binary. I then execute this binary using spawn-fcgi -p 8000 -n <binary> or cgi-fcgi -start -connect localhost:8000 ./<binary>. I have had success doing this and displaying the correct results. However, when I do this, the CGI script is the only thing that is being displayed on the web server. I cannot go to any .html page or any other page for that matter. Even if I type in a random extension which should result in a 404 Page not Found error, the CGI script is being displayed. Basically I'm trying to have a index.html be the home page and then when the user clicks on a button, the user is taken to a new page that displays the C CGI script.
Is this possible? If so, how could I do it? I have spent hours trying to find a solution online but have had no success. Please let me know if the question is too vague/unclear or if you need more information! Thank you!
There are two possibilities that I can think of. You can assign a URI to your CGI program and use that to access it. Or you can send any invalid URI to your CGI program.
In the first case, you could use:
root /nginx/html;
index index.html index.htm new.html;
location / {
try_files $uri $uri/ =404;
}
location /api {
fastcgi_pass 127.0.0.1:8000;
}
So, any URI beginning with /api will be sent to the CGI program. Other URIs will be served by nginx, unless not found, in which case a 404 response will be returned.
In the second case, you could use:
root /nginx/html;
index index.html index.htm new.html;
location / {
try_files $uri $uri/ #api;
}
location #api {
fastcgi_pass 127.0.0.1:8000;
}
So any URI that does not exist will be sent to the CGI program.
See this document for the try_files directive, and this document for the location directive.