Tutorial

How To Set Up a Node.js Application for Production on Ubuntu 14.04

Published on December 4, 2014
How To Set Up a Node.js Application for Production on Ubuntu 14.04
Not using Ubuntu 14.04?Choose a different version or distribution.
Ubuntu 14.04

Introduction

Node.js is an open source Javascript runtime environment for easily building server-side and networking applications. The platform runs on Linux, OS X, FreeBSD, and Windows, and its applications are written in JavaScript. Node.js applications can be run at the command line but we will teach you how to run them as a service, so they will automatically restart on reboot or failure, so you can use them in a production environment.

In this tutorial, we will cover setting up a production-ready Node.js environment that is composed of two Ubuntu 14.04 servers; one server will run Node.js applications managed by PM2, while the other will provide users with access to the application through an Nginx reverse proxy to the application server.

The CentOS version of this tutorial can be found here.

Prerequisites

This guide uses two Ubuntu 14.04 servers with private networking (in the same datacenter). We will refer to them by the following names:

  • app: The server where we will install Node.js runtime, your Node.js application, and PM2
  • web: The server where we will install the Nginx web server, which will act as a reverse proxy to your application. Users will access this server’s public IP address to get to your Node.js application.

It is possible to use a single server for this tutorial, but you will have to make a few changes along the way. Simply use the localhost IP address, i.e. 127.0.0.1, wherever the app server’s private IP address is used.

Here is a diagram of what your setup will be after following this tutorial:

Reverse Proxy to Node.js Application

Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on both of your servers–this is the user that you should log in to your servers as. You can learn how to configure a regular user account by following steps 1-4 in our initial server setup guide for Ubuntu 14.04.

If you want to be able to access your web server via a domain name, instead of its public IP address, purchase a domain name then follow these tutorials:

Let’s get started by installing the Node.js runtime on the app server.

Install Node.js

We will install the latest LTS release of Node.js, on the app server.

On the app server, let’s update the apt-get package lists with this command:

  1. sudo apt-get update

Then use apt-get to install the git package, which npm depends on:

  1. sudo apt-get install git

Go to the Node.js Downloads page and find the Linux Binaries (.tar.xz) download link. Right-click it, and copy its link address to your clipboard. At the time of this writing, the latest LTS release is 4.2.3. If you prefer to install the latest stable release of Node.js, go to the appropriate page and copy that link.

Change to your home directory and download the Node.js source with wget. Paste the download link in place of the highlighted part:

  1. cd ~
  2. wget https://nodejs.org/dist/v4.2.3/node-v4.2.3-linux-x64.tar.gz

Now extract the tar archive you just downloaded into the node directory with these commands:

  1. mkdir node
  2. tar xvf node-v*.tar.?z --strip-components=1 -C ./node

If you want to delete the Node.js archive that you downloaded, since we no longer need it, change to your home directory and use this rm command:

  1. cd ~
  2. rm -rf node-v*

Next, we’ll configure the global prefix of npm, where npm will create symbolic links to installed Node packages, to somewhere that it’s in your default path. We’ll set it to /usr/local with this command:

  1. mkdir node/etc
  2. echo 'prefix=/usr/local' > node/etc/npmrc

Now we’re ready to move the node and npm binaries to our installation location. We’ll move it into /opt/node with this command:

  1. sudo mv node /opt/

At this point, you may want to make root the owner of the files:

  1. sudo chown -R root: /opt/node

Lastly, let’s create symbolic links of the node and npm binaries in your default path. We’ll put the links in /usr/local/bin with these commands:

  1. sudo ln -s /opt/node/bin/node /usr/local/bin/node
  2. sudo ln -s /opt/node/bin/npm /usr/local/bin/npm

Verify that Node is installed by checking its version with this command:

  1. node -v

The Node.js runtime is now installed, and ready to run an application! Let’s write a Node.js application.

Create Node.js Application

Now we will create a Hello World application that simply returns “Hello World” to any HTTP requests. This is a sample application that will help you get your Node.js set up, which you can replace it with your own application–just make sure that you modify your application to listen on the appropriate IP addresses and ports.

Because we want our Node.js application to serve requests that come from our reverse proxy server, web, we will utilize our app server’s private network interface for inter-server communication. Look up your app server’s private network address.

If you are using a DigitalOcean droplet as your server, you may look up the server’s private IP address through the Metadata service. On the app server, use the curl command to retrieve the IP address now:

  1. curl -w "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address

You will want to copy the output (the private IP address), as it will be used to configure our Node.js application.

Hello World Code

Next, create and open your Node.js application for editing. For this tutorial, we will use vi to edit a sample application called hello.js:

  1. cd ~
  2. vi hello.js

Insert the following code into the file, and be sure to substitute the app server’s private IP address for both of highlighted APP_PRIVATE_IP_ADDRESS items. If you want to, you may also replace the highlighted port, 8080, in both locations (be sure to use a non-admin port, i.e. 1024 or greater):

hello.js
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8080, 'APP_PRIVATE_IP_ADDRESS');
console.log('Server running at http://APP_PRIVATE_IP_ADDRESS:8080/');

Now save and exit.

This Node.js application simply listens on the specified IP address and port, and returns “Hello World” with a 200 HTTP success code. This means that the application is only reachable from servers on the same private network, such as our web server.

Test Application (Optional)

If you want to test if your application works, run this node command on the app server:

  1. node hello.js

Note: Running a Node.js application in this manner will block additional commands until the application is killed by pressing CTRL+C.

In order to test the application, open another terminal session and connect to your web server. Because the web server is on the same private network, it should be able to reach the private IP address of the app server using curl. Be sure to substitute in the app server’s private IP address for APP_PRIVATE_IP_ADDRESS, and the port if you changed it:

  1. curl http://APP_PRIVATE_IP_ADDRESS:8080

If you see the following output, the application is working properly and listening on the proper IP address and port:

Output:
Hello World

If you do not see the proper output, make sure that your Node.js application is running, and configured to listen on the proper IP address and port.

On the app server, be sure to kill the application (if you haven’t already) by pressing CTRL+C.

Install PM2

Now we will install PM2, which is a process manager for Node.js applications. PM2 provides an easy way to manage and daemonize applications (run them as a service).

We will use Node Packaged Modules (NPM), which is basically a package manager for Node modules that installs with Node.js, to install PM2 on our app server. Use this command to install PM2:

  1. sudo npm install pm2 -g

Manage Application with PM2

PM2 is simple and easy to use. We will cover a few basic uses of PM2.

Start Application

The first thing you will want to do is use the pm2 start command to run your application, hello.js, in the background:

  1. pm2 start hello.js

This also adds your application to PM2’s process list, which is outputted every time you start an application:

Output:
┌──────────┬────┬──────┬──────┬────────┬───────────┬────────┬────────────┬──────────┐ │ App name │ id │ mode │ PID │ status │ restarted │ uptime │ memory │ watching │ ├──────────┼────┼──────┼──────┼────────┼───────────┼────────┼────────────┼──────────┤ │ hello │ 0 │ fork │ 5871 │ online │ 0 │ 0s │ 9.012 MB │ disabled │ └──────────┴────┴──────┴──────┴────────┴───────────┴────────┴────────────┴──────────┘

As you can see, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.

Applications that are running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot). Luckily, PM2 provides an easy way to do this, the startup subcommand.

The startup subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots. You must also specify the platform you are running on, which is ubuntu, in our case:

  1. pm2 startup ubuntu

The last line of the resulting output will include a command (that must be run with superuser privileges) that you must run:

Output:
[PM2] You have to run this command as root [PM2] Execute the following command : [PM2] sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u sammy --hp /home/sammy"

Run the command that was generated (similar to the highlighted output above) to set PM2 up to start on boot (use the command from your own output):

  1. sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u sammy --hp /home/sammy"

Other PM2 Usage (Optional)

PM2 provides many subcommands that allow you to manage or look up information about your applications. Note that running pm2 without any arguments will display a help page, including example usage, that covers PM2 usage in more detail than this section of the tutorial.

Stop an application with this command (specify the PM2 App name or id):

  1. pm2 stop example

Restart an application with this command (specify the PM2 App name or id):

  1. pm2 restart example

The list of applications currently managed by PM2 can also be looked up with the list subcommand:

  1. pm2 list

More information about a specific application can be found by using the info subcommand (specify the PM2 App name or id)::

  1. pm2 info example

The PM2 process monitor can be pulled up with the monit subcommand. This displays the application status, CPU, and memory usage:

  1. pm2 monit

Now that your Node.js application is running, and managed by PM2, let’s set up the reverse proxy.

Set Up Reverse Proxy Server

Now that your application is running, and listening on a private IP address, you need to set up a way for your users to access it. We will set up an Nginx web server as a reverse proxy for this purpose. This tutorial will set up an Nginx server from scratch. If you already have an Nginx server setup, you can just copy the location block into the server block of your choice (make sure the location does not conflict with any of your web server’s existing content).

On the web server, let’s update the apt-get package lists with this command:

  1. sudo apt-get update

Then install Nginx using apt-get:

  1. sudo apt-get install nginx

Now open the default server block configuration file for editing:

  1. sudo vi /etc/nginx/sites-available/default

Delete everything in the file and insert the following configuration. Be sure to substitute your own domain name for the server_name directive (or IP address if you don’t have a domain set up), and the app server private IP address for the APP_PRIVATE_IP_ADDRESS. Additionally, change the port (8080) if your application is set to listen on a different port:

/etc/nginx/sites-available/default
server {
    listen 80;

    server_name example.com;

    location / {
        proxy_pass http://APP_PRIVATE_IP_ADDRESS:8080;
        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 example.com, accessing http://example.com/ via a web browser would send the request to the application server’s private IP address on port 8080, which would be received and replied to by the Node.js application.

You can add additional location blocks to the same server block to provide access to other applications on the same web server. For example, if you were also running another Node.js application on the app server on port 8081, you could add this location block to allow access to it via http://example.com/app2:

Nginx Configuration — Additional Locations
    location /app2 {
        proxy_pass http://APP_PRIVATE_IP_ADDRESS:8081;
        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;
    }

Once you are done adding the location blocks for your applications, save and exit.

On the web server, restart Nginx:

  1. sudo service nginx restart

Assuming that your Node.js application is running, and your application and Nginx configurations are correct, you should be able to access your application via the reverse proxy of the web server. Try it out by accessing your web server’s URL (its public IP address or domain name).

Conclusion

Congratulations! You now have your Node.js application running behind an Nginx reverse proxy on Ubuntu 14.04 servers. This reverse proxy setup is flexible enough to provide your users access to other applications or static web content that you want to share. Good luck with your Node.js development!

Also, if you are looking to encrypt transmissions between your web server and your users, here is a tutorial that will help you get HTTPS (TLS/SSL) support set up.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
92 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Why use a proxy?

It’s insecure to run any node app at 80 port (because only root have access to ports 0-1024, and in this case nodejs must run with root privileges). See https://groups.google.com/forum/?fromgroups=#!topic/nodejs/gB8veFbcX5g

What’s the reason that the nginx server is run on a separate droplet? Is it also security-related?

Security - If you proxy server gets compromised, your app server might still be fine. Scalability&Flexibility - It’s really easy to switch the app server. It’s also easier to scale the proxy&app servers horizontally and vertically with this setup.

Is it insecure even with setcap to run on port 80?

+1 for it being insecure. But if a process can be hijacked thru http putting nginx in front of it won’t help, except the attacker won’t have root access, but if it has vulnerabilities exposed over tcp or other underlying protocol, nginx can save you.

Better question: Why run the nginx server on a separate droplet?

What could be the reason I’m getting the error EADDRNOTAVAIL when executing node hello.js ?

I’m having the same problem. It seem to work when I switch it to my public ip… Did you ever figure out how to fix it?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
January 9, 2015

Are both of your servers in the same data center with private networking?

Same problem for me, On the initial droplet setup I forgot to set private networking, so I stopped the droplet turned private networking on and restarted, but still get the same issue, any ideas. This is before any interaction with the web server, so can only assume the app server is at fault somewhere.

Creating from scratch with private networking turned on, fixes the issue.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
January 14, 2015

If you create a droplet without private networking then enable private networking later, you must set up the new network interface on your system: How To Enable DigitalOcean Private Networking on Existing Droplets.

god, can they just say something on the private network page, point to this article as manicas pointed out, took me forever to find out.

I had a similar issue. For me, it was because a prerequisite tutorial had disallowed port 3000. If you followed a previous tutorial, try sudo ufw allow 3000/tcp

run pm2 stop hello.js

If we are using nginx here, maybe we can use some additional cache settings? So nginx can serve all static files, and node will wake up only for executing some logic.

Andrew SB
DigitalOcean Employee
DigitalOcean Employee badge
January 13, 2015

Definetly. This is just an example of how to set up the basic infrastructure. For a deeper dive into what you can do with Nginx, check out:

If I want to run my node.js app across 3 nodes with multi-core processors, PM2 can help me achieve that? I know PM2 helps me run my app across a single server with multi-core support, but if I have more nodes, Can I use PM2 or need a load-balancer like Haproxy or Nginx Proxy?

Digital Oceans always on top of their game. I have been using Monit and Upstart directly, but this seems like a quicker alternative. Thanks.

What are the advantages of suing PM2 vs using something like nodejs forever + nohup?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
January 20, 2015

Basically, PM2 has more features. Both can be used to keep an application running.

Great tutorial, but why you are not using NPM to install node instead? @manicas Secondly, if we are using only a single server to be APP and WEB, what would it affect?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
March 4, 2015

You can use a single server to run both components (I think it’s mentioned in the tutorial somewhere). Separating them makes scaling easier, and isolates the web tier from the applications.

Thanks @manicas I found out that using node v0.12 requires twice of this steps to complete installation of node:

*Configure and build Node.js with the following commands: ./configure make

Now, to install Node.js, run this command sudo make install*

I hope it helps for the future install.

Cheers

npm is part of node… so is it even possible to use it to install node?

hi Please could you tell me … Is it Ok (good ?) to use for creating the app server the image “Node -v 0.12 on 14.04” provided under the *“Create Droplet -Application” * menu ?

That’s what I’m doing an it’s working fine. As far as I’m aware it just means you get to skip the installing node bit.

Does it also work with node+socket.io (two way communication)?

Hi! i have this:

g++: internal compiler error: Killed (program cc1plus) Please submit a full bug report, with preprocessed source if appropriate. See <file:///usr/share/doc/gcc-4.8/README.Bugs> for instructions. make[1]: *** [/root/node-v0.12.0/out/Release/obj.target/v8_base/deps/v8/src/api.o] Error 4 make[1]: Leaving directory `/root/node-v0.12.0/out’ make: *** [node] Error 2

What happened?

Wonderful stuff! Question is how can I prevent directory browsing of my root folder when running my app in Ubuntu? Can nginx help me save my world in this case? if I run my web server on port 8000 and my rest api on 8001 how can nginx help me start both in one command :(

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
March 11, 2015

Just create a separate server block for each app (listening port). Check out this tutorial: How To Set Up Nginx Server Blocks

@manicas I’m kind of confused on what the following do to the HTTP headers:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;

What is HTTP Upgrade? How does that have to do with reverse proxy?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
April 9, 2015

Those headers are necessary when proxying a WebSocket.

Also how does the nginx built-in load balancer compare to pm2’s?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
April 9, 2015

I haven’t used it, but I believe the PM2 load balancer performs load balancing at the Node process level, where Nginx is used for network load balancing.

This was a really excellent guide, just the info I needed to get started, thanks!

Thanks for the guide. I assuming that if I configure nginx accordingly I can use this set up for a) multiple domains, and b) multiple app servers. Am I correct in that assumption?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
April 14, 2015

Yes, that is correct.

@manicas, great tutorial.

My connection was hanging until I commented out the following line,

proxy_set_header Connection 'upgrade';

Do you have any idea why this would happen?

Thank you for this. I was stuck on a 502 Bad Gateway error for awhile until I scrolled deep into the comments and found this. Removed the line and poof it works. Thanks. Wish I knew why that fixed everything but for now I’ll take the win.

When using nginx I am able to access my nodejs app at the URL myapp.com/home, but if I navigate to myapp.com I still get the nginx welcome page. Is there a fix for this?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
April 20, 2015

Did you set your location directive to “/home” ? It should look like this:

    location / {

Thanks Mitchell. Wonderful post and has helped us setting our Nodejs production environment. We are facing issue where Nginx is not severing updated HTML files which is part of one nodejs application.

Do Ngnix cache all static contents by default? If yes, then what is the location of caching in Ubantu? Or it doesnt cache, can you pls help with providing required conf setting for this. Googled alot but not able to find the solution.

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
April 27, 2015

By default, nginx does not cache any files. You can configure nginx so serve static files and pass everything else to Node.js like this:

server {
    listen 80;

    server_name example.com;
    root /path/to/nodejs/app/static

    location / {
        try_files $uri @nodejs;
    }

    location @nodejs {
        proxy_pass http://APP_PRIVATE_IP_ADDRESS:8080;
        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;
    }
}

Great post! Now I’m truly ready for production. Digital Ocean you are really good!

Stupid question, but which droplet should the actual domain name (e.g. example.com) be registered to: the WEB droplet or the APP droplet?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
May 13, 2015

The WEB droplet (the reverse proxy web server) is the server that users will access, so your domain name should point there.

If your domain is using the DigitalOcean DNS, you can follow this tutorial for help on setting that up: How To Set Up a Host Name with DigitalOcean.

I get this, whats missing or wrong ?

pm2 hello.js [PM2] Spawning PM2 daemon Error: spawn ENOENT at errnoException (child_process.js:988:11) at Process.ChildProcess._handle.onexit (child_process.js:779:34) Error: spawn ENOENT at errnoException (child_process.js:988:11) at Process.ChildProcess._handle.onexit (child_process.js:779:34) Did you forgot to call pm2.connect(function() { }) before interacting with PM2 ?

the part about PM2 will save my life some day…

I have read dozens of other ways to restart an app after reboot but NONE worked. Maybe because my app runs in /home/myUser and this is not yet ready when the server boots and the configured files are started?

Well, PM2 works well.

Actually: today a digital ocean server went down momentarily (first time in two years and about 6 apps) and my application didn’t restart after reboot - that’s why I finally found this article. It won’t happen again!

thanks!

Thank you! This was really informative and well explained! I only had one problem, but the problem did not stop me from setting everything up. Running sudo npm install pm2 -g gave me errors regarding git. I realized I did not have git installed. But even after installation of git I got a new error: “npm WARN optional dep failed, continuing fsevents@0.3.6”

Well, Its working atleast! I am also just using one server.

I couldn’t get my private ip address, what should i input to my command prompt exactly?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
June 28, 2015

Try ip addr or ifconfig

Extremely easy to follow and just what I needed to deploy! Thanks!

Very nice tutorial, nginx is returning a 404, after a redirect from my node app to a static login page (the login page didn’t load. should i have another configuration if node is using ui-route? or does it have a conflict with static content being serve by node?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
August 11, 2015

I’m not sure what your app or configuration looks like, but you may have to configure nginx URL rewrites.

In my application with nodejs + redis + rails, can i use this configuration for node and use this (https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-passenger-and-nginx-on-ubuntu-14-04) for my rails app? With some changes, off course.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
August 17, 2015

Could you describe your setup?

Great tutorial! Works perfectly for me.

You can start a droplet with nodejs already installed, is it safe to skip your install step? or is there something different compared to yours.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
August 24, 2015

Yes, the one-click lets you skip the Install Node.js section.

Adding additional locations other than a root ‘/’ domain it not working for me. The additional locations just redirects to the default nginx page or to the app deployed to / (if any)

In the example below /uds will redirect to the default nginx page if I replace the /uds with / - it’s getting to my node app.

server {
    listen 80;

    server_name mydomain.com;

    location /uds {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Hi I followed this blog. I am using one Digital Ocean droplet to set up. I end up with a error of 502 Bad Gateway.

Do you know what I can do to fix this?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
August 28, 2015

Double check which port and IP address your Node app is listening on (}).listen(8080, '10.10.10.10'); , and make sure your Nginx configuration matches that (proxy_pass http://10.10.10.10:8080;`). Then restart your app and Nginx. If your app is on the same server as Nginx, you can use localhost instead of the private IP address.

Thanks for the amazing tutorial! Really helped! One problem: when I access my app by it’s domain+port like http://www.site.com:8000 it works fine, I can see all data and all. But when I access without the port, it doesn’t show any of the data. Weird part: when I add data from the address WITHOUT the port, it adds normally, but shows only on the app WITH the 8000 port, and not on the one without port. What should I do?

Hi everybody, I do not understand why sometines you do use sudo and sometines you don’t.

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
September 8, 2015

Hi. As a user, you usually have write access to your home directory only (and some other directories that are usually writeable by everyone, such as /tmp). In order to use commands that need write access to system files like apt-get that installs programs globally outside of your home directory, you need to escalate to root which has access to everything on the server. sudo is a command that it used to run commands and programs as a different user, which is root by default.

I always read on the web that node.js web applications should work under non root user like user1 for the example. But if we use sudo too under user1, files and directories for the application belong to user1 but belong to root group. So, is it a security problem to do that way or not ? That is the question…

Hello, I have a problem, with this settings nginx doesnt load the website when accessed with “www.” because it’s a subdomain, how can I do this? I have tried this in nginx config default ( /etc/nginx/sites-available/default ) : server { listen 80; server_name www.domain.com; return 301 $scheme://domain.com$request_uri; }

server { listen 80;

server_name domain.com;
location / {
    proxy_pass http://127.0.0.1:8080;
    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;
}

}

I found this in stackoverflow but it doesnt work, how can i make www. to redirect to non-www or at least be able to see the website also with www?

Thank you for your help!

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
September 23, 2015

Did you add the necessary DNS records? Check out this tutorial: How To Redirect www to Non-www with Nginx on Ubuntu 14.04

Thank you manicas, I’ve found the info some minutes after posting my comment.

Thanks, interesting and informative read!

Hello,

I am newbie in administration of server. Should I use two droplets with ubuntu for this example? Did I understand it right?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
November 6, 2015

Hi. Yes, the tutorial is for two Droplets. However, you can set it up on a single Droplet as well.

Node source mentioned is very old. Current Node version 5.0.0

Would be nice to see the article being updated once in a while…

Current Node is newer, but it’s likely that many people running Node in production are using the 4.x because it’s LTS.

is it possible to setup 2 reverse proxy to point to Node.js application server ?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
November 30, 2015

Yes, you can point two reverse proxies to the same application server.

Awesome tutorial! Been using this on my droplet for a while and it all worked well. But now when I’m updated my source code and done ubuntu updates, nginx/pm2 crashed and I dont have any idea why really. For starter I had a problem running pm2 without “sudo” but I think I figured that out, and now to the remaining problem: When visiting the site in the browser I get 502 Bad gateway, and when looking at the log I get this:

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()

and I dont get any errors when running nginx -t. So a little out of my knowledge right now.

Have been looking around in the nginx files and /etc/nginx/sites-available/default and /etc/nginx/sites-enabled/default contains the same information and that is the only thing I can think of?

The configuration for nginx are as in the tutorial.

Hi, i did my setup at the end of tutorial like this server { listen 80;

server_name www.myPortfolio.com;
      
location / {
    proxy_pass http://my_private_ip:8080;
    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;
}

}
Now, my next step it’s to upload my front-end via filezilla thats what i put host: 159.203.22.215 username: me password: XXXXXXX port: 8080

then somehow i still get Connecting to 159.203.22.215:8080… Status: Connection attempt failed with “ECONNREFUSED - Connection refused by server”. Error: Could not connect to server

i need help !!! :(

Update: I set up my Filezilla setting by adding my private ssh key. Somehow it convert to ppk format and i get this error now…

Status: Waiting to retry… Status: Connecting to www.mySite.com:80… Response: fzSftp started, protocol_version=4 Command: keyfile “/Users/me/.ssh/id_rsa_filezilla.ppk” Command: open “andy@www.me.com” 80 Error: Server unexpectedly closed network connection Error: Could not connect to server

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
December 9, 2015

SFTP uses port 22 (by default). You need to use that instead of 80 in order to be able to connect to your droplet using FileZilla.

Thanks a lot

Did this all just change in the last two weeks? I swear the commands are different from when I went through this last month and now the commands like “yum” and “systemctl” aren’t being recognized and I don’t remember them from before. I’m on Ubuntu 14.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
December 9, 2015

Sorry about that. I updated this and the CentOS version of the tutorial to use a new version of Node, and I mixed the two of them up.

The content should be accurate now.

I have been trying to figure out how to point the server to my static page that i store it up somewhere in my cloud server. Also, i am using NodeJs as my backend.

My new problem: After this new configuration that i did, it points me to a 404 page instead of pointing to my index.html

Also, in the line 20, it gives me an error of duplicate “/” when i run sudo nginx -t for debugging purpose

````nginx: [emerg] duplicate location "/" in /etc/nginx/sites-enabled/default:20 ````

here’s my Nginx configuration file…

    server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        server_name www.andii90s.com;

        root /home/andy/www/myProjectX/app;
        index index.html index.htm;


        location / {
            proxy_pass http://10.137.10.140:8080;
            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 / {
            #Line 20
            try_files $uri $uri/ =404;
        }

        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
           root /home/andy/www/myProjectX/app;
        }
    } 

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
December 15, 2015

There is a conflict because you have two location / blocks. Nginx will send the /index.html request to your Node app (where the file doesn’t exist).

Can you change the location of your Nodejs proxy block to something else (e.g. location /myapp)?

I have to put location /home/andy/www/myProjectX/app ?@manicas

Is there a way to do this on an apache server that points to a subdomain e.g. node.example.com instead of IP_ADDRESS:8080? Forgive me if this is a silly question. Very new to it all.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
December 16, 2015

Yes. You have to configure the following:

  • DNS record that points node.example.com to ip_address
  • Configure your reverse proxy (the one that forwards traffic to Node on port 8080) server block to listen on port 80 (or 443)

You can also simply skip the reverse proxy portion, and configure your Node app to listen on port 80 (or 443).

Thanks. I added the following to my /etc/apache2/sites-available/000-default.conf and it works as I hoped.

<VirtualHost *:80> ServerAdmin emailme@example.com ServerName node.example.com ServerAlias node.example.com ProxyPass / http://node.example.com:8080 ProxyPassReverse / http://node.example.com:8080 </VirtualHost>

Do I have to have two droplets—one for app and the other for web—for this to work?

Hey,

I’m a bit confused and lost. Does the APP_PRIVATE_ID_ADDRESS equal with the “Droplet/Settings/ (Networking tab) Private Network/Private IP” ??

Actually, i’m running my nodejs locally on a Raspberry Pi, so my app’s private IP is 192.168.2.111 for example. So the question is, should i run the nodejs app to listen to this IP and the custom port, and also add this http://192.168.2.1111:9999 to the nginx server config as the proxy_pass?

I’m kinda newbie to this to be honest =(

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
January 20, 2016

Could you describe your setup and what you are trying to do? This tutorial, which uses private IP addresses, only works if the Nginx server can reach the NodeJS server.

Well, the Raspberry Pi is behind a router, so i think the Nginx server wont be able to reach the Pi. I should get fix IP somehow, then port forwarding etc… am i right? =/

I think i’m going to host the app on the droplet, it will be easier.

Thanks for your answer btw.

Hi Mitchell, great tutorial! How could I serve a second app on a second server block?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
February 2, 2016

If you’re using the same server setup, you can run your second app on a different port and add a second location to your Nginx server that proxies to the second app.

What I intend to do is accessing the second app via a different domainname pointing to the same IP address. Sumular to the example about static files. (How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 14.04 LTS)

I tried to serve a second app on port 8081, and connect it with a second server block file, when I restart nginx it fails an I receive the following error log: 2016/02/02 11:21:23 [emerg] 5447#0: invalid port in upstream "10.135.0.205:8081

I´m able to connect the app with curl http://10.135.0.205:8081

content of my server block file:

server { listen 80;

server_name sidejob.ch;

location / {
    proxy_pass http://10.135.0.205:8081>;
    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;
}

}

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
February 2, 2016

Remove that > at the end of your proxy_pass.

oh no, a typo, sorry for bothering you for that!

OK, now the nginx is restarting without problems, but when I connect via browser, I still get the content of your default server block example on port 8080 instead of my second app content on port 8081.

If i’d wanted to make a GET request to the nodejs from my website like this:

< script src =" urltothefile /file. js" > < / script >

how would i do that?!

Hello Sir I have configured Nginx successfully and it works well. For example I could visit my site from http://123.123.123.123. But I can also visit it from inner port like: http://123.123.123.123:7999, is this result normal or I should do something to ban the 7999 connections ? By the way the Nginx and Nodejs are on the same instance and the app was started by : sudo npm start. The conf file is like this: server { listen 80; server_name 123.123.123.123;

location / {
    proxy_pass http://127.0.0.1:7999;
    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;
}

}

Thanks a lot, Sir, your tutorial is excellent and very easy to learn.

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
March 4, 2016

Change your node app to listen on 127.0.0.1, not the public IP address.

I have my app running on http://PRIVATE_IP:3000 My droplet configured to MY_DOMAIN.com in Networks. My nginx file at /etc/nginx/sites-available/default configured to

server {
    listen 80;
    server_name MY_DOMAIN.com;

    location / {
        proxy_pass http://PRIVATE_IP:3000;
        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;
    }
} 

And I have restarted nginx. But i can only connect to MY_DOMAIN.com:3000 not MY_DOMAIN.com . Any ideas why?

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
March 4, 2016

What is your output from these commands:

netstat -na | grep :80
netstat -na | grep :3000

tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN

tcp6 0 0 :::3000 :::* LISTEN

Mitchell Anicas
DigitalOcean Employee
DigitalOcean Employee badge
March 7, 2016

It looks like your app isn’t using the private network interface.

For me to get pm2 restarting to work I had to run** $ pm2 save** after I had run sudo su -c “env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u sammy --hp /home/sammy”

I found this on https://serversforhackers.com/node-process-management-with-pm2

Hello, I have created two droplets:

  1. Web Server(not installed NGINX yet, as operating system Ubuntu)
  2. App Server(have enabled the IP-adress, installed “MEAN Stack one-click-app” and as Operatiog System Ubuntu)

Well, I have create at my App Server the “hello.js” file for testing like the example above:

var http = require(‘http’); http.createServer(function (req, res) { res.writeHead(200, {‘Content-Type’: ‘text/plain’}); res.end(‘Hello World\n’); }).listen(8080, ‘APP_PRIVATE_IP_ADDRESS’); console.log(‘Server running at http://APP_PRIVATE_IP_ADDRESS:8080/’);

The app is running at my App server and at my Web server I want to run the command “curl http://APP_PRIVATE_IP_ADDRESS:8080” for testing but it happened nothing. Just the connection timed out.

In Menu Networking I have set the domains for the app server as follow:

A: @ -> public IP CNAME www - mydomain

What I did wrong?

After run the sudo command to set pm2 up on boot, you have to run “pm2 save”. With this, your app will run too…

This comment has been deleted

    Excellent Tutorial. Helped me publish my very first app. Thank you!

    for some reason when i use curl to test if the hello.js app is working on the web server it doesnt work

    curl: (7) Failed to connect to xx.xxx.xx.xx port 8080: Connection timed out

    It doesn’t work with my routes in node (it gives me an 404 error). Anyone knows what can I do to solve this issue?

    Thanks

    Thanks for this tutorial! Simple and useful, that’s the way I like it.

    Critical step:

    After you do a pm2 start hello.js, I had to do a pm2 save, before I daemonized. Otherwise when I did a sudo service pm2 restart my application did not get spawned automatically (Ubuntu 14.04, node v4.4.5).

    I was getting an error when using pm2: /usr/bin/env: node: No such file or directory

    And I found the solution, in case anyone was searching for it: I had installed node.js with this method: sudo apt-get install nodejs

    this installs node as “nodejs” instead of “node” (there is another Ubuntu package named “node” that is a Ham Radio program), so pm2 couldn’t find it. So, I found this fix:

    sudo ln -s /usr/bin/nodejs /usr/bin/node

    this creates a symbolic link from “nodejs” to “node”. Now pm2 can continue as expected. You might want to be sure you don’t need to use a ham radio on your server before using this fix though ;)

    Missing a slash…should be:

    sudo mv node/ /opt

    The line sudo npm install pm2 -g shouldn’t include sudo. You should never run npm as sudo! There’s a help page on the npm website to fix the sudo problem - https://docs.npmjs.com/getting-started/fixing-npm-permissions

    my pm2 not woking at restart the machine…

    pm2 start hello.js pm2 startup ubuntu

    [PM2] Generating system init script in /etc/init.d/pm2-init.sh
    [PM2] Making script booting at startup...
    [PM2] -ubuntu- Using the command:
          su -c "chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults"
    
    
    [PM2] Done.
    

    su -c “chmod +x /etc/init.d/pm2-init.sh && update-rc.d pm2-init.sh defaults” pm2 save

    [PM2] Saving current process list...
    [PM2] Successfully saved in /root/.pm2/dump.pm2
    

    App working :)

    shutdown -r now

    waiting start…

    App not working :(

    pm2 list

    no running

    I create symbolic links of the node and npm, but node -v does not work. I install node by apt-get install nodejs-legacy

    but my pm2 does not start at boot

    I change my /etc/init.d/pm2-init.sh “export PM2_HOME =”/root/.pm2"" to “export PM2_HOME =”/home/node/.pm2""

    and it worked :)

    Hey Team,

    After configuring nginx along with domain name. I am getting ngix successful configuration message but not the node js message which should be Hello World in this case. Any help would be appreciated.

    Hi i got this problem, when I use 127.0.0.1 in the app server everything works fine, but when I use my private network address it crashes and shows me the following message:

    events.js:141 throw er; // Unhandled ‘error’ event ^

    Error: listen EADDRNOTAVAIL 10.132.83.150:8080 at Object.exports._errnoException (util.js:874:11) at exports._exceptionWithHostPort (util.js:897:20) at Server._listen2 (net.js:1221:19) at listen (net.js:1270:10) at net.js:1379:9 at doNTCallback3 (node.js:452:9) at process._tickCallback (node.js:358:17) at Function.Module.runMain (module.js:469:11) at startup (node.js:136:18) at node.js:963:3

    Please need help,

    I tried the application (hello.js) following this tutorial and all was ok. But I tried another app that contains static files and it doesn’t work. What’s the problem ? thanks

    For this instruction i am getting not found

    curl -w “\n” http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address not found

    Hi,

    Am trying to setup multiple domain multiple app nginx node.js apps with https, and so far only one of them works at a time. my setup is as follows for the sites-enabled.

    I hope someone can spot the mistake, thanks a lot

    default

    # HTTP - redirect all requests to HTTPS:
    server {
            listen 80;
            listen [::]:80 default_server ipv6only=on;
            return 301 https://$host$request_uri;
    }
    

    domain1.com

    server {
            listen 443;
            server_name domain1.com, www.domain1.com;
    
            ssl on;
            # Use certificate and key provided by Let's Encrypt:
            ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    
            # Pass requests for / to localhost:8080:
            location / {
                    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_cache_bypass $http_upgrade;
                    proxy_redirect off;
            }
    } 
    

    domain2.com

    server {
            listen 443;
            server_name domain2.com, www.domain2.com;
    
            ssl on;
            # Use certificate and key provided by Let's Encrypt:
            ssl_certificate /etc/letsencrypt/live/domain2.com/fullchain.pem;
            ssl_certificate_key /etc/letsencrypt/live/domain2.com/privkey.pem;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    
            # Pass requests for / to localhost:8080:
            location / {
                    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;
                    #DIFFERENT PORT
                    proxy_pass http://localhost:3000/;
                    proxy_ssl_session_reuse off;
                    proxy_set_header Host $http_host;
                    proxy_cache_bypass $http_upgrade;
                    proxy_redirect off;
            }
    }
    

    Thanks for the guide.

    I’ve set up my Nginx proxy and it works just fine. But when I try to access the ip and port directly, I get an unable to connect error.

    That is: http://mydomain.com works just fine

    But: http://myserverip:port fails

    Yes, the server ip alone returns the default Nginx page. But add the port and the error occurs. Should my default Nginx config have a proxy in it too?

    This command:

    curl -w "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address
    

    Returns not found.

    I’m not sure how I’m supposed to determine my private IP address. Can I use the eth1 ip address? It looks like it’s a 10.x.x.x non-routable IP.

    To some people it is probably obvious but I struggled for a bit on the part about the server_name in the config file. I was putting the private_ip as the server_name instead of the public ip since the article does not specify. Most people probably won’t have this issue but I slipped up and wasted a good hour or so. Just a heads up. Great article by the way!

    JFYI… when creating Node.js applications you might need to store configuration items in a file. Instead of keeping them in cleartext, use the masterkey package as mentioned here: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

    How to check is my proxy server is working or not. I follow all the above step to set my proxy server but how I know that proxy server is really working.

    I’m doing like this

    My node app :

    const fs = require('fs');
    const https = require('https');
    const express    = require('express'); 
    const app        = express(); 
    
    var router = express.Router();  
    
    router.get('/',function(req,res){
        	// console.log("Route = /");
        	res.json({"success" : 1})
    });
    
    app.use('/api/v2', router);
    
    app.listen(8080);
    
    

    My proxy config :

    server {
        listen 80;
    
        server_name APP_PRIVATE_IP_ADDRESS;
    
        location / {
            proxy_pass http://APP_PRIVATE_IP_ADDRESS:8080;
            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 blog providing good information To learn NodeJS visit http://iwebworld.info contact: iwebworldinfo@gmail.com

    I’m getting the error EADDRNOTAVAIL when executing node hello.js, and I am using both Node.JS and nginx at the same droplet. When using private IP, it cause this error and hello.js never works, but using localhost or the public ip, it is working ( but not accessd via browser, I can access it using another terminal and login into the root to test it).

    I finally have figured out! for those who want to run both nginx and Node.js in the same droplet, please copy the following in your /etc/nginx/sites-available file:

    upstream @backend {
        server 127.0.0.1:3000;
    }
    
    server
    {
        listen 80;
        listen [::]:80;
        server_name domain.com www.domain.com;
    
        location /
        {
            proxy_pass http://@backend;
    
            proxy_buffers 16 32k;
            proxy_buffer_size 64k;
            proxy_busy_buffers_size 128k;
            proxy_cache_bypass $http_pragma $http_authorization;
            proxy_connect_timeout 59s;
            proxy_hide_header X-Powered-By;
            proxy_http_version 1.1;
            proxy_ignore_headers Cache-Control Expires;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_no_cache $http_pragma $http_authorization;
            proxy_pass_header Set-Cookie;
            proxy_read_timeout 600;
            proxy_redirect off;
            proxy_send_timeout 600;
            proxy_temp_file_write_size 64k;
            proxy_set_header Accept-Encoding '';
            proxy_set_header Cookie $http_cookie;
            proxy_set_header Host $host;
            proxy_set_header Proxy '';
            proxy_set_header Referer $http_referer;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Original-Request $request_uri;
        }
    }
    

    change the domain.com to your website name. then, in your Node.js app, you need to have server listen to 3000, ‘localhost’

    For starters who are not comfortable on the command line, this is simply a no go for many. This is where a tool like opscaptain can help you deploy Node.js applications to your digitalocean droplet the easy way with either a simple upload from the dashboard or run [opscaptain deploy] and that is it. No need to fiddle with bash scripts and maintain them. Simply connect your droplet and you are ready to deploy. https://www.opscaptain.com/nodejs-hosting

    hi ,

    i am running npm app.js instead the actual directory and it is successful but when i close putty the application stops running and says site cant be reached . This is happening recently in digital ocean server

    You’ve GOT to be kidding!!

    Thanks for the guide.

    I’ve set up my Nginx proxy and it works just fine. But when I try to access the ip and port directly, I get an unable to connect error.

    That is: http://mydomain.com works just fine

    But: http://myserverip:port fails

    Yes, the server ip alone returns the default Nginx page. But add the port and the error occurs. Should my default Nginx config have a proxy in it too?

    This command:

    curl -w "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address
    

    Returns not found.

    I’m not sure how I’m supposed to determine my private IP address. Can I use the eth1 ip address? It looks like it’s a 10.x.x.x non-routable IP.

    To some people it is probably obvious but I struggled for a bit on the part about the server_name in the config file. I was putting the private_ip as the server_name instead of the public ip since the article does not specify. Most people probably won’t have this issue but I slipped up and wasted a good hour or so. Just a heads up. Great article by the way!

    JFYI… when creating Node.js applications you might need to store configuration items in a file. Instead of keeping them in cleartext, use the masterkey package as mentioned here: https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

    How to check is my proxy server is working or not. I follow all the above step to set my proxy server but how I know that proxy server is really working.

    I’m doing like this

    My node app :

    const fs = require('fs');
    const https = require('https');
    const express    = require('express'); 
    const app        = express(); 
    
    var router = express.Router();  
    
    router.get('/',function(req,res){
        	// console.log("Route = /");
        	res.json({"success" : 1})
    });
    
    app.use('/api/v2', router);
    
    app.listen(8080);
    
    

    My proxy config :

    server {
        listen 80;
    
        server_name APP_PRIVATE_IP_ADDRESS;
    
        location / {
            proxy_pass http://APP_PRIVATE_IP_ADDRESS:8080;
            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 blog providing good information To learn NodeJS visit http://iwebworld.info contact: iwebworldinfo@gmail.com

    I’m getting the error EADDRNOTAVAIL when executing node hello.js, and I am using both Node.JS and nginx at the same droplet. When using private IP, it cause this error and hello.js never works, but using localhost or the public ip, it is working ( but not accessd via browser, I can access it using another terminal and login into the root to test it).

    I finally have figured out! for those who want to run both nginx and Node.js in the same droplet, please copy the following in your /etc/nginx/sites-available file:

    upstream @backend {
        server 127.0.0.1:3000;
    }
    
    server
    {
        listen 80;
        listen [::]:80;
        server_name domain.com www.domain.com;
    
        location /
        {
            proxy_pass http://@backend;
    
            proxy_buffers 16 32k;
            proxy_buffer_size 64k;
            proxy_busy_buffers_size 128k;
            proxy_cache_bypass $http_pragma $http_authorization;
            proxy_connect_timeout 59s;
            proxy_hide_header X-Powered-By;
            proxy_http_version 1.1;
            proxy_ignore_headers Cache-Control Expires;
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
            proxy_no_cache $http_pragma $http_authorization;
            proxy_pass_header Set-Cookie;
            proxy_read_timeout 600;
            proxy_redirect off;
            proxy_send_timeout 600;
            proxy_temp_file_write_size 64k;
            proxy_set_header Accept-Encoding '';
            proxy_set_header Cookie $http_cookie;
            proxy_set_header Host $host;
            proxy_set_header Proxy '';
            proxy_set_header Referer $http_referer;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Original-Request $request_uri;
        }
    }
    

    change the domain.com to your website name. then, in your Node.js app, you need to have server listen to 3000, ‘localhost’

    For starters who are not comfortable on the command line, this is simply a no go for many. This is where a tool like opscaptain can help you deploy Node.js applications to your digitalocean droplet the easy way with either a simple upload from the dashboard or run [opscaptain deploy] and that is it. No need to fiddle with bash scripts and maintain them. Simply connect your droplet and you are ready to deploy. https://www.opscaptain.com/nodejs-hosting

    hi ,

    i am running npm app.js instead the actual directory and it is successful but when i close putty the application stops running and says site cant be reached . This is happening recently in digital ocean server

    You’ve GOT to be kidding!!

    I have two app server , both need to run npm build before pm2 start , built command generate dist folder , each app different content in dist folder. Am using load balancer with upsteam backend but its getting issue, that is ,first time any user load web site and he may connect to app1 server from the upsteam ,and if he reload once again it will connect second app server, this time he con’t load website correctly because dist folder files will miss mach, can u plz suggest better solution , am looking both app can use one dist folder or any other better solution is there.

    I find the best solution always here. Thanks Digital Ocean

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Become a contributor for community

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    DigitalOcean Documentation

    Full documentation for every DigitalOcean product.

    Resources for startups and SMBs

    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

    Get our newsletter

    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

    New accounts only. By submitting your email you agree to our Privacy Policy

    The developer cloud

    Scale up as you grow — whether you're running one virtual machine or ten thousand.

    Get started for free

    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

    *This promotional offer applies to new accounts only.