Using nginx as a reverse proxy in front of your Node.js application
This is a straight to point short tutorial on how to set up NGINX as a reverse proxy in front of a Node.js application, and although this is not mandatory, there are several benefits of doing so, as answered in this Stack Overflow question:
- Not having to worry about privileges/setuid for the Node.js process. Only root can bind to port 80 typically. If you let nginx/Apache worry about starting as root, binding to port 80, and then relinquishing its root privileges, it means your Node app doesn’t have to worry about it.
- Serving static files like images, CSS, js, and HTML. Node may be less efficient compared to using a proper static file web server (Node may also be faster in select scenarios, but this is unlikely to be the norm). On top of files serving more efficiently, you won’t have to worry about handling eTags or cache control headers the way you would if you were servings things out of Node. Some frameworks may handle this for you, but you would want to be sure. Regardless, still probably slower.
- More easily display meaningful error pages or fall back onto a static site if your node service crashes. Otherwise users may just get a timed out connection.
- Running another web server in front of Node may help to mitigate security flaws and DoS attacks against Node. For a real-world example, CVE-2013-4450 is prevented by running something like Nginx in front of Node.
So, with being convinced that having NGINX in front of Node.js application is a good thing, following are the steps on how to install and configure it.
First, update the apt-get package lists with the following command:
sudo apt-get update
Then install NGINX using apt-get:
sudo apt-get install nginx
Now open the default server block configuration file for editing:
sudo vi /etc/nginx/sites-available/default
and add this to it:
server { listen 80; server_name meantodo.com; location / { proxy_pass http://127.0.0.1:1337; 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; } }
This configures the web server to respond to requests at its root. Assuming our server is available at http://meantodo.com, accessing it via a web browser would send the request to the application server’s private IP address on port 1337, which would be received and replied to by the Node.js application.
Once you’re done with the setting you have to run the following command which will restart NGINX:
sudo service nginx restart
You can learn more about additional NGINX setting from quite a load of tutorials.
Thanks man, works perfect. Now I have to learn what each proxy_* do
Thanks, I’m glad this helped you! Always be learning 😉
Thank you for sharing, work like a charm ^_^
Thanks for the post.
I don’t understand how nginx gets a shot at serving static files, if all the requests are proxied to node. What am I missing?
You’re right. For that, this post may help: http://stackoverflow.com/questions/869001/how-to-serve-all-existing-static-files-directly-with-nginx-but-proxy-the-rest-t/15467555#15467555
what is the port 1337?
That port is the port on which your Node.js app is running. Note that this is just an example, you may use some other, but make sure you update it correctly in the nginx config in that case.
I’m still getting the default Nginx static welcome page after this.
And you’ve done everything exactly as I wrote? Are you sure you restarted nginx at the end?
I tried your approach above and I also tried using apache2 using this link https://www.digitalocean.com/community/tutorials/how-to-use-apache-as-a-reverse-proxy-with-mod_proxy-on-ubuntu-16-04 but nothing is helping at all.
Hello !
I have the same problem that has been reported, which came closest to my problem. I need to start the server.js when I execute ionic serve
So I’m trying to run the command
Sudo vi / etc / nginx / sites-available / default
And the following occurs:
~
~
~
~
~
~
~
~
~
~
~
“/etc/nginx/sites-available/default” [New DIRECTORY]
I’m doing this on a Mac The Sierra 10.12.3
Ok but if you are accessing it from a computer on the web, you make a post to a domain (configured to the router IP), then you route traffic to the nginx server, which should route it to the nodejs app. But I can get it to work. Here is my config file:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name subdomain.domain.com;
ssl_certificate /etc/letsencrypt/live/subdomain.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.com/privkey.pem;
root /www/subdomain.domain.com/aism;
index index.php index.html index.htm;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# Error & Access logs
error_log /www/subdomain.domain.com/logs/error.log error;
access_log /www/subdomain.domain.com/logs/access.log;
location / {
index index.html index.php;
proxy_pass http://192.168.1.53:442;
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;
}
location ~ /.well-known {
allow all;
}
location /public {
root /www/subdomain.domain.com/aism;
}
location ~ ^/(images/|img/|javascript/|js/|css/|stylesheets/|flash/|media/|static/) {
}
}
2017/09/25 05:11:28 [error] 377#377: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 202.62.18.64, server: m.forher.co.id, request: “GET / HTTP/1.1”, upstream: “http://127.0.0.1:7712/”, host: “m.forher.co.id”
2017/09/25 05:12:51 [error] 377#377: *7 directory index of “/var/www/html/” is forbidden, client: 104.181.128.56, server: _, request: “POST / HTTP/1.1”, host: “188.166.239.130”
i get this error. i thought port is not available where i can config it the port ?. my folder app in /var/www/myapp. is it wrong ?. on sites-enabled root “/var/www/html/”. pleas help me. thanks for answering
server {
listen 80;
server_name m.forher.co.id;
client_max_body_size 200M;
location / {
include /etc/nginx/mime.types;
client_max_body_size 200M;
proxy_pass http://localhost:7712;
proxy_buffers 32 25m;
proxy_busy_buffers_size 25m;
proxy_buffer_size 24m;
proxy_ignore_headers “Cache-Control” “Expires”;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection ”;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 240000;
proxy_connect_timeout 240000;
proxy_send_timeout 240000;
proxy_intercept_errors off;
send_timeout 2400000;
}
}
this my sites-enabled
Where does the private IP address come from? An app isn’t assigned a private IP by uploading it. Everything else makes sense.
You’re right, thanks!
Hello,
I want to have a static html site to be loaded by default on / request and when the user will click on a specific button, it should load my application with /login url.
So in short, I want to configure a static website + nodejs web application on the same server using single nginx reverse proxy.
I tried creating several location blocks but my bad 🙁
Please help me out
How to server the next page like I host this website
https://itsanishjain.ml
and it give the output
but
https://itsanishjain.ml/notification give 404 error