ageitgey / node-unfluff

Automatically extract body content (and other cool stuff) from an html document
Apache License 2.0
2.15k stars 223 forks source link

Author is not accurate #110

Open chan-dev opened 4 years ago

chan-dev commented 4 years ago

I've tested the package in using this URL.

And this is the result: You can see that author property.

 {
  data: {
    title: "How To Set Up a Node.js Application for Production on Ubuntu 16.04",
    softTitle:
      "How To Set Up a Node.js Application for Production on Ubuntu 16.04",
    date: "UpdatedNovember 1, 2016 1.4m views",
    author: ["By Brennen Bearnes UpdatedNovember 1, 2016 1.4m views"],
    publisher: "DigitalOcean",
    copyright:
      '. Contents. Share. Twitter. Facebook. Hacker News. Share. Twitter. Facebook. Hacker News. ×. Sign up for our newsletter.. Get the latest tutorials on SysAdmin and open source topics.. Sign Up. Thanks for signing up!. DigitalOcean home. Products. Pricing. Docs. Product Docs. API Docs. Sign in. Sign in to. Community. Control Panel. Tutorials. Questions. Get Involved. Participate. Hub for Good. Supporting each other to make an impact. Write for DigitalOcean. You get paid, we donate to tech non-profits.. Hacktoberfest. Contribute to Open Source. Build with DigitalOcean. Community Tools and Integrations. Hatch Startup Program. Marketplace Partner Program. Solutions Partner Program. Presentation Grants. DigitalOcean on GitHub. Search DigitalOcean. /. Sign Up. Community. Tutorials. Questions. Write for Us. Hacktoberfest. Tools. Products. Homepage. Pricing. Product Overview. Marketplace. Customers. Control Panel. Documentation. Contact Support. Contact Sales. Sign In. Related. Node.js on DigitalOcean. Marketplace. NGINX Config Generator. Tool. How To Build a Concurrent Web Scraper with Puppeteer, Node.js, Docker, and Kubernetes. Tutorial. How To Build a REST API with Prisma and PostgreSQL. Tutorial. Tutorial. How To Set Up a Node.js Application for Production on Ubuntu 16.04. NginxNode.jsLet\'s EncryptUbuntu 16.04. By Brennen Bearnes. UpdatedNovember 1, 2016. 1.4m views. Not using Ubuntu 16.04?. Choose a different version or distribution.. CentOS 7. Debian 9. Debian 8. Debian 10. Ubuntu 20.04. Ubuntu 18.04. Ubuntu 16.04. 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. Node.js applications can be run at the command line, but we’ll focus on running them as a service, so that they will automatically restart on reboot or failure, and can safely be used in a production environment.. In this tutorial, we will cover setting up a production-ready Node.js environment on a single Ubuntu 16.04 server. This server will run a Node.js application managed by PM2, and provide users with secure access to the application through an Nginx reverse proxy. The Nginx server will offer HTTPS, using a free certificate provided by Let’s Encrypt.. Prerequisites. This guide assumes that you have the following:. An Ubuntu 16.04 server, configured with a non-root user with sudo privileges, as described in the initial server setup guide for Ubuntu 16.04.. A domain name pointed at your server’s public IP, as per How to Set Up a Host Name with DigitalOcean. This tutorial will use example.com throughout.. Nginx installed, covered in How To Install Nginx on Ubuntu 16.04. Nginx configured with SSL using Let’s Encrypt certificates. How To Secure Nginx with Let’s Encrypt on Ubuntu 16.04 will walk you through the process.. When you’ve completed the prerequisites you will have a server serving the default Nginx placeholder page at https://example.com/.. Let’s get started by installing the Node.js runtime on your server.. Install Node.js. We will install the latest LTS release of Node.js, using the NodeSource package archives.. First, you need to install the NodeSource PPA in order to get access to its contents. Make sure you’re in your home directory, and use curl to retrieve the installation script for the Node.js 6.x archives:. cd ~. curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh. You can inspect the contents of this script with nano (or your preferred text editor):. nano nodesource_setup.sh. And run the script under sudo:. sudo bash nodesource_setup.sh. The PPA will be added to your configuration and your local package cache will be updated automatically. After running the setup script from nodesource, you can install the Node.js package in the same way that you did above:. sudo apt-get install nodejs. The nodejs package contains the nodejs binary as well as npm, so you don’t need to install npm separately. However, in order for some npm packages to work (such as those that require compiling code from source), you will need to install the build-essential package:. sudo apt-get install build-essential. The Node.js runtime is now installed, and ready to run an application! Let’s write a Node.js application.. Note: When installing from the NodeSource PPA, the Node.js executable is called nodejs, rather than node.. Create Node.js Application. We will write 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 with your own application–just make sure that you modify your application to listen on the appropriate IP addresses and ports.. Hello World Code. First, create and open your Node.js application for editing. For this tutorial, we will use nano to edit a sample application called hello.js:. cd ~. nano hello.js. Insert the following code into the file. If you want to, you may replace the highlighted port, 8080, in both locations (be sure to use a non-admin port, i.e. 1024 or greater):. hello.js#!/usr/bin/env nodejs. var http = require(\'http\');. http.createServer(function (req, res) {. res.writeHead(200, {\'Content-Type\': \'text/plain\'});. res.end(\'Hello World\\n\');. }).listen(8080, \'localhost\');. console.log(\'Server running at http://localhost:8080/\');. Now save and exit.. This Node.js application simply listens on the specified address (localhost) and port (8080), and returns “Hello World” with a 200 HTTP success code. Since we’re listening on localhost, remote clients won’t be able to connect to our application.. Test Application. In order to test your application, mark hello.js executable:. chmod +x ./hello.js. And run it like so:. ./hello.js. OutputServer running at http://localhost:8080/. 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 on your server, and connect to localhost with curl:. curl http://localhost:8080. If you see the following output, the application is working properly and listening on the proper address and port:. OutputHello 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 address and port.. Once you’re sure it’s working, 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 in the background as a service).. We will use npm, a package manager for Node modules that installs with Node.js, to install PM2 on our server. Use this command to install PM2:. sudo npm install -g pm2. The -g option tells npm to install the module globally, so that it’s available system-wide.. 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:. pm2 start hello.js. This also adds your application to PM2’s process list, which is outputted every time you start an application:. Output[PM2] Spawning PM2 daemon. [PM2] PM2 Successfully daemonized. [PM2] Starting hello.js in fork_mode (1 instance). [PM2] Done.. ┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐. │ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │. ├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤. │ hello │ 0 │ fork │ 3524 │ online │ 0 │ 0s │ 21.566 MB │ disabled │. └──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘. Use `pm2 show <id|name>` to get more details about an app. 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:. pm2 startup systemd. The last line of the resulting output will include a command that you must run with superuser privileges:. Output[PM2] Init System found: systemd. [PM2] You have to run this command as root. Execute the following command:. sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy. Run the command that was generated (similar to the highlighted output above, but with your username instead of sammy) to set PM2 up to start on boot (use the command from your own output):. sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy. This will create a systemd unit which runs pm2 for your user on boot. This pm2 instance, in turn, runs hello.js. You can check the status of the systemd unit with systemctl:. systemctl status pm2-sammy. For a detailed overview of systemd, see Systemd Essentials: Working with Services, Units, and the Journal.. 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):. pm2 stop app_name_or_id. Restart an application with this command (specify the PM2 App name or id):. pm2 restart app_name_or_id. The list of applications currently managed by PM2 can also be looked up with the list subcommand:. pm2 list. More information about a specific application can be found by using the info subcommand (specify the PM2 App name or id):. pm2 info example. The PM2 process monitor can be pulled up with the monit subcommand. This displays the application status, CPU, and memory usage:. pm2 monit. Now that your Node.js application is running, and managed by PM2, let’s set up the reverse proxy.. Set Up Nginx as a Reverse Proxy Server. Now that your application is running, and listening on localhost, you need to set up a way for your users to access it. We will set up the Nginx web server as a reverse proxy for this purpose.. In the prerequisite tutorial, we set up our Nginx configuration in the /etc/nginx/sites-available/default file. Open the file for editing:. sudo nano /etc/nginx/sites-available/default. Within the server block you should have an existing location / block. Replace the contents of that block with the following configuration. If your application is set to listen on a different port, update the highlighted portion to the correct port number.. /etc/nginx/sites-available/default. . .. location / {. proxy_pass http://localhost: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 server to respond to requests at its root. Assuming our server is available at example.com, accessing https://example.com/ via a web browser would send the request to hello.js, listening on port 8080 at localhost.. You can add additional location blocks to the same server block to provide access to other applications on the same server. For example, if you were also running another Node.js application on port 8081, you could add this location block to allow access to it via http://example.com/app2:. /etc/nginx/sites-available/default — Optional location /app2 {. proxy_pass http://localhost: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.. Make sure you didn’t introduce any syntax errors by typing:. sudo nginx -t. Next, restart Nginx:. sudo systemctl restart nginx. Assuming that your Node.js application is running, and your application and Nginx configurations are correct, you should now be able to access your application via the Nginx reverse proxy. Try it out by accessing your 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 an Ubuntu 16.04 server. 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!. You rated this helpful.. Undo. You reported this tutorial.. Undo. Was this helpful?. Yes. No. 95. Report an issue. About the authors. Brennen Bearnes. has authored 48 tutorials.. Related. Tutorial. How To Build a Concurrent Web Scraper with Puppeteer, Node.js, Docker, and Kubernetes. In this tutorial, you will use Node.JS, Puppeteer, Docker, and Kubernetes to build a highly scalable scraper that can simultaneously extract data from multiple pages. You will test your scraper on the dummy bookstore, books.toscrape.com, where you will scrape data from 400 pages in ~30 seconds.. Tutorial. How To Build a REST API with Prisma and PostgreSQL. Prisma is an open source database toolkit. In this tutorial, you will build a REST API for a small blogging application in TypeScript using Prisma and a PostgreSQL database. At the end of the tutorial, you will have a web server running locally on your machine that can respond to various HTTP requests and read and write data in the database.. Tutorial. How To Scrape a Website Using Node.js and Puppeteer. In this tutorial, you will build a web scraping application using Node.js and Puppeteer. Your app will grow in complexity as you progress. First, you will code your app to open Chromium and load a special website designed as a web-scraping sandbox: [books.toscrape.com](books.toscrape.com). In the next two steps, you will scrape all the books on a single page of books.toscrape and then all the books across multiple pages. Then you will filter your scraping by category and save your data as JSON.. Tutorial. How To Launch Child Processes in Node.js. Since Node.js instances create a single process with a single thread, JavaScript operations that take a long time to run can sometimes block the execution of other code. A key strategy to work around this problem is to launch a child process to run multiple processes concurrently. In this tutorial, you will use the child_process module to create child processes while executing a series of sample Node.js applications.. Still looking for an answer?. Ask a question. Search for more help. Comments. Follow-Up Questions. 95 Comments. Sign In to Comment. Load. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.. Become a contributor. You get paid; we donate to tech nonprofits.. Get our biweekly newsletter. Sign up for Infrastructure as a Newsletter.. Hub for Good. Working on improving health and education, reducing inequality, and spurring economic growth? We\'d like to help.. Featured on Community. Kubernetes Course. Learn Python 3. Machine Learning in Python. Getting started with Go. Intro to Kubernetes. DigitalOcean Products. Droplets. Managed Databases. Managed Kubernetes. Spaces Object Storage. Marketplace. Welcome to the developer cloud. DigitalOcean makes it simple to launch in the cloud and scale up as you grow – whether you’re running one virtual machine or ten thousand.. Learn More. DigitalOcean Homepage. ©. document.write(new Date().getFullYear());. DigitalOcean, LLC. All rights reserved.. Company. About. Leadership. Blog. Careers. Partners. Referral Program. Press. Legal. Security & Trust Center. Products. Pricing. Products Overview. Droplets. Kubernetes. Managed Databases. Spaces. Marketplace. Load Balancers. Block Storage. API Documentation. Documentation. Release Notes. Community. Tutorials. Q&A. Tools and Integrations. Tags. Product Ideas. Write for DigitalOcean. Presentation Grants. Hatch Startup Program. Shop Swag. Research Program. Open Source. Code of Conduct. Contact. Get Support. Trouble Signing In?. Sales. Report Abuse. System Status. Almost there!. Sign in to your Community account or create a new one below.. Sign In. Sign Up. $(function() {. createDistroVersionSelection({. $distro_version: $(\'#distribution_version\'),. see_more_link: \'/community/tutorial_collections/how-to-set-up-a-node-js-application-for-production\'. });. });. $(function() {. window.initHelpfulnessActions(1957, \'/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04/flag\');. });. $(function() {. if (!!window.init_sharing) {. window.init_sharing();. }. new window.NewsletterSignup();. new window.GrowableMarkdown({ target: \'[data-growable-markdown]\' });. });. {"@context":"http://schema.org","@type":"Article","name":"How To Set Up a Node.js Application for Production on Ubuntu 16.04","headline":"How To Set Up a Node.js Application for Production on Ubuntu 16.04","alternativeHeadline":"How To Set Up a Node.js Application for Production on Ubuntu 16.04","description":"Node.js is an open source JavaScript runtime environment for easily building server-side and networking applications. Node.js applications can be run at the command line but this guide focuses on running them as a service using PM2, so that they will automatically restart on reboot or failure, and can safely be used in a production environment.","keywords":"Node.js,Let\'s Encrypt,Nginx,Ubuntu 16.04","url":"https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04"},"dateModified":"2019-09-18T19:54:21Z","inLanguage":"en","accessMode":"textual","accessModeSufficient":"textual","isAccessibleForFree":true,"license":"https://creativecommons.org/licenses/by-nc-sa/4.0/","publishingPrinciples":"https://www.digitalocean.com/community/tutorials/technical-recommendations-and-best-practices-for-digitalocean-s-tutorials","author":[{"@type":"Person","name":"Brennen Bearnes","@id":"https://www.digitalocean.com/community/users/bpb"}],"datePublished":"2016-05-12T17:08:23Z","image":{"@type":"ImageObject","url":"https://www.digitalocean.com/assets/community/illustrations/DigitalOcean_Community-e00e73a18df20667c3117725e727f3ade330204dff619ad8153050ded7341627.jpg","height":375,"width":750},"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"http://schema.org/LikeAction","userInteractionCount":"286"},{"@type":"InteractionCounter","interactionType":"http://schema.org/CommentAction","userInteractionCount":"77"}],"sourceOrganization":{"@type":"Organization","name":"DigitalOcean Community","url":"https://www.digitalocean.com/community"},"publisher":{"@type":"Organization","name":"DigitalOcean","url":"https://www.digitalocean.com","logo":{"@type":"ImageObject","url":"https://assets.digitalocean.com/logos/DO_Logo_horizontal_blue.png","width":351,"height":60}},"comment":[{"comment":{"@context":"http://schema.org","@type":"Comment","text":"In case the react app has react router. How will the config file change for router to work because this configuration doesnot seem to work with react router it would give 404 on react routes."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I would just add that after “Note: When installing from the NodeSource PPA, the Node.js executable is called nodejs, rather than node.” It is necessary to create a simlink: ln -s /usr/bin/nodejs /usr/bin/node When I followed the tutorial, PM2 complained about “node” executable name. I solved the issue with the simlink. "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Big thanks for this post!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hi, I’m hoping someone can help me figure out why part of this tutorial isn’t working for me. I’m following along with an Express app I’ve already built instead of the example Node app. Everything is working correctly until I run the long command to start the pm2 process on reboot. After doing so, when I run this command: systemctl status pm2-sammy It says the process is Loaded but that it’s Inactive (Dead). If anyone could help me figure out why this is happening, I would really appreciate it. The app is working correctly both if I just run it with nodejs and if I run it in the background with pm2. I just want to ensure it starts back up if the server reboots."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"if the application code is on my local machine, how do I copy it to the digital ocean sever ? which folder should it be copied to ? "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I am trying to run two different apps in the same server but with no success. The two apps use Express and Node.js, here is what I’ve tried so far: location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. proxypass http://localhost:4001; proxyhttpversion 1.1; proxysetheader Upgrade $httpupgrade; proxysetheader Connection ‘upgrade’; proxysetheader Host $host; proxycachebypass $httpupgrade; proxysetheader X-Real-IP $remoteaddr; proxysetheader X-NginX-Proxy true; proxysetheader X-Forwarded-For $proxyaddxforwardedfor; proxyredirect off; } location /angry-pigs { rewrite /angry-pigs/(.*)$ /$1 break; proxypass http://localhost:5010; proxyhttpversion 1.1; proxysetheader Upgrage $httpupgrade; proxysetheader Connection \'upgrade’; proxycachebypass $httpupgrade; proxysetheader X-Real-IP $remoteaddr; proxysetheader X-NginX-Proxy true; proxysetheader X-Forwarded-For $proxyaddxforwardedfor; proxyredirect off; }"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Great article, I am looking for some steps to deploy the releases on a daily basis. How do i do it what are the steps to follow. Deploy the changeset 2.Restart the server And if you can the best practices that would be great."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I tried with pm2 startup systemd and then executed the command as in the output sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u user --hp /home/user I encountered the following error. bin/sh: 1: systemctl: not found [ERROR] Exit code : 127 [PM2][ERROR] systemctl enable pm2-ays failed, see error above. How to solve this? System = Ubuntu 16.04 x64"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hello, I followed the tutorial and it works, but I need to configure the server to run a Nuxt.js app. On their website there are instructions for something I think is to be put in /etc/nginx/sites-available/… (https://nuxtjs.org/faq/nginx-proxy/). However I do not understand what is the addres of the Node.js instance to substitute. Moreover I was wondering: why would I want to use Nginx as a proxy? Cannot I just upload my app in the /var/www/html folder? Sorry if I am saying stupid things, I am a beginner.. :-)"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hi, Thanks for the great tutorial. I tried to add a second location block as follow location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. #try_files $uri $uri/ =404; proxy_pass http://localhost: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; } location /test { proxy_pass http://localhost: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; } However, the app only works for the 1st location ( location / ). It doesn’t work for the ( location /test ), although it refers to the same app running at port 8081. Does anybody know what is the problem? The app is actually a node.js. Does it have anything to do with node.js configuration?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Starting processes that receive command line argument, e.g. pm2 start server.js --name MyServer -- -h localhost -p 8080 requires a dump of the running process list to be saved using pm2 save in order for the processes to start again after reboot using systemd. I don’t know if this is also true for processes that don’t need arguments, but this is at least the case for me. So I think this guide should contain something about pm2 save"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I have a question, I made all the process for a Front End app and I got the https to work on a domain, now I trying to implement https in the API works with the Front-End in the same server but of course in a different port. No matters what I do I keep getting this error 400 The plain HTTP request was sent to HTTPS port Can anybody help me?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"In case anyone is having problems with websockets throwing errors when trying to set up HTTPS: WebSocket connection to \'ws://.../socket.io/?EIO=2\\u0026transport=websocket\\u0026sid=p3af7ZNfvogtq6tAAAG0\' failed: Error during WebSocket handshake: Unexpected response code: 400. Add the following to your configuration: location / { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \\"upgrade\\"; proxy_set_header Host $host; } The solution was found on an issue opened on the socket-io repo: Error during WebSocket handshake: Unexpected response code: 400"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"This worked to get pm2, itself, to run after restarting Linux, but it wasn’t actually restarting any of the Node processes. For that, I needed to do: pm2 save As mentioned on the pm2 Startup usage page. After that, pm2 would start my Node app after a Linux reboot."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"This is a great article, as all of these tutorials are. I do want to suggest an addendum, though. I started up an Express app using the express-session module (connected to Redis) to manage user sessions, and I had a heck of a time figuring out why secure cookies weren’t working. The main key seems to have been that I needed to set this in the sites-available file for the reverse proxy configuration block: proxy_set_header X-Forwarded-Proto $scheme It’s talked about in this article a bit, though not in the context of Node. https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching I also set the trust proxy in the Express app and specifically set the proxy setting to true in my session config. But the main thing was just to convey secure connection info from Nginx to Node."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"hi I can’t get my helloworld app working — when I curl http://localhost:8080 I’m getting there error: curl: (7) Failed to connect to localhost port 8080: Connection refused I’ve tried destroying and rebuilding the droplet to make sure everything is installed properly but got same error. Any suggestions?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"thanks for this guide! super helpful and explains all the right things. i’ve used it to set up a few servers already."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hello, I found this tutorial very helpful, I got my site up and running with https and I’m receiving ‘hello world’ in the browser. However, I’d like to add a sub-domain which is going to be running on the same droplet (my root is blakehschwartz.com and I’d like to add portfolio.blakehschwartz.com.) I’ve looked at a couple of other tutorials as well, and can’t figure out if I can just add to my existing server block or if I need to add a separate one (this one mentions using separate server blocks, but the config also looks a lot more manual/hard-coded). I’m also unsure if I can piggy back off my existing root domain ports or if I need to assign new ones (seems like I should be able to use 80 and 443 for the public part and maybe use localhost:8081 for the proxy part. Also, like another asked a while back - where do I place my web files for the root and subdomains? In the past I’ve used shared hosting where each one had it’s own ftp directory, and I just put everything in /var/www/html respectively. It looks like nginx is using location / to reference /var/www/html since that’s where my helloworld.js file is, but how would that work with a subdomain? Here’s my current server block for reference: # HTTP - redirect all requests to HTTPS: server { listen 80; listen [::]:80 default_server ipv6only=on; return 301 https://$host$request_uri; } # HTTPS - proxy requests on to local Node.js app: server { listen 443; server_name blakehschwartz.com; ssl on; # Use certificate and key provided by Let\'s Encrypt: \\u003cssl stuff\\u003e # Pass requests for / to localhost:8080: location / { \\u003cproxy stuff\\u003e } } Any help would be great, thanks!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Awesome tutorial!! Thanks!!!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"After replacing the contents of the default file with the code provided in the Configure Nginx for HTTPS section, I’m getting the following error. nginx: [emerg] duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/default~:4 nginx: configuration file /etc/nginx/nginx.conf test failed I’m not sure why line 4 would be having a problem since that part stays the same after copying the text. Does anyone know what could be causing this problem?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"In the SSL configuration with LetsEncrypt, the following line needs to be changed from; listen 443; to listen 443 ssl; This is as per instructions from Nginx http://nginx.org/en/docs/http/configuring_https_servers.html"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I am getting https : Secure on the URL bar, but the website is not loaded. I am getting this error: ** 502 Bad Gateway nginx/1.10.0 (Ubuntu)** Any suggestions on this one ?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"-systemd- Using the command: su sammy -c “pm2 dump \\u0026\\u0026 pm2 kill” \\u0026\\u0026 su root -c “systemctl daemon-reload \\u0026\\u0026 systemctl enable pm2 \\u0026\\u0026 systemctl start pm2” Command failed: /bin/sh -c su sammy -c “pm2 dump \\u0026\\u0026 pm2 kill” \\u0026\\u0026 su root -c “systemctl daemon-reload \\u0026\\u0026 systemctl enable pm2 \\u0026\\u0026 systemctl start pm2” bash: systemctl: command not found I did change sammy to my user account."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":" proxy_ssl_session_reuse off; for what reason? There is no any ssl connection to the upstream:proxy_pass http://..."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hey guys! I’ve written a script that does all of this with just one line of code pasted into the terminal! https://github.com/marcotriglia/ubuntu_16.04_nodejs_server_setup Give it a star if you like it, it would mean a lot!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"if you have this error: npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.14: wanted {“os”:“darwin”,“arch”:“any”} (current: {“os”:“linux”,“arch”:“x64”}) ubuntu *you can use this line * : * sudo npm install -g npm@3.8.9*"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Just add another comment, if you need http2, it is quite simple, just change listen 443; to listen 443 http2;"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"This tutorial worked before. But since I stop nginx, when I try to start it again. It dose not listen on 8080 any more. When I run lsof -i :8080 it returns nothing now. When I open my website, it shows: 502 Bad Gateway What may cause this? Thanks"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Also I had error after ./letsencrypt-auto certonly –standalone Creating virtual environment... Traceback (most recent call last): File \\"/usr/lib/python3/dist-packages/virtualenv.py\\", line 2363, in \\u003cmodule\\u003e main() File \\"/usr/lib/python3/dist-packages/virtualenv.py\\", line 719, in main symlink=options.symlink) File \\"/usr/lib/python3/dist-packages/virtualenv.py\\", line 988, in create_environment download=download, File \\"/usr/lib/python3/dist-packages/virtualenv.py\\", line 918, in install_wheel call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT) File \\"/usr/lib/python3/dist-packages/virtualenv.py\\", line 812, in call_subprocess % (cmd_desc, proc.returncode)) OSError: Command /.local/s...ncrypt/bin/python2.7 - setuptools pkg_resources pip wheel failed with error code 1 In my case, before running letsencrypt-auto: $ export LC_ALL=\\"C\\" did the trick."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"For those, who using CloudFlare and getting error after Let’s Encrypt attempt, read this TL;DR: You don’t need to stop nginx Instead of using $ ./letsencrypt-auto certonly --standalone use: $ ./letsencrypt-auto certonly --webroot --webroot-path /var/www/YOUR_WWW_PATH/ --renew-by-default --email YOURMAIL@example.com --text --agree-tos -d YOURDOMAIN.com -d www.YOURDOMAIN.com"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"In what folder should I start developing my Node.js Application? I plan on creating a MEAN (MongoDB, Express.js, Angular.js, Node.js) Application but I don’t know if I should place it on a folder like /var/www/{my_project_name} or should it be on /home/{my_username}/{my_project_name} or on /home/{dedicated_username_for_the_project}/{my_project_name} ?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I’m getting this error when I try to retrieve the initial certificate: run this: $ ./letsencrypt-auto certonly --standalone and get this: Failed authorization procedure. fooproject.com (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to 000.000.000.000:443 for TLS-SNI-01 challenge, not my actual domain name or ip address pasted above Shouldn’t let’s encrypt be trying to connect to port 80?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hey, just found an error: The “server_name” line needs to appear in the HTTP block, not the HTTPS block. Placing it in the first block produces perfect results. Phenomenal walk through, Digital Ocean puts it down."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Why is the reverse proxy necessary or desirable? Can’t you just let node serve the app directly? Does using a proxy interfere with socket.io communication between server/client?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I see that in this guide you put both the reverse proxy as well as the node server on one droplet. In the 14.04 guide, they used a separate droplet for the reverse proxy and a separate droplet for the node.js app. Could you explain the rationale a bit behind when and why it would be good to host these servers on separate droplets? For example, at what point would it start to make sense to look at using the nginx server as a load balancer and have multiple app droplets running in parallel? I’m trying to decide if we need multiple separate droplets for DB, app, nginx etc. or if we can get by with just one droplet for all three services at this stage."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"This is great. Do you have a tutorial on setting up passport to allow social logins. Most importantly, an explaination of how to ensure that site content isn’t accessible without logging in. I’ve tried this but seem to be missing the point of callback URIs. Also it seems that most tutorials out there don’t cover where to put your app on your server. I assume it doesn’t matter."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"using nvm + 16.04 + node 4.4.5 and running pm2 startup ubuntu and when i restart it it doesn’t load up the hello.js process… help!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I was on an nginx Odyssey that could have been avoided if the code snippet for /etc/nginx/sites-enabled/default under Configure Nginx for HTTPS showed it being wrapped in http { }. This was certainly a very rookie mistake, but that’s why I’m here in the first place. :) It’s all up and running now! For people searching, the error I was getting was nginx: [emerg] \\"server\\" directive is not allowed here in /etc/nginx/nginx.conf"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I’m hung up on running the Hello World app. I keep getting the error: ./hello.js: line 1: syntax error near unexpected token `(\' ./hello.js: line 1: `var http = require(\'http\');\' I’ve tried inputting the code using nano and vi; and I’ve tried typing it and copy/pasting it, always deleting hello.js between attempts. Any clues?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"pm2 startup systemd should be change to pm2 startup ubuntu ?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Thanks for the tutorial - i was able to set it up as described but am facing an issue with renewing my letsencrypt certificate now - when I run the cron process to renew the certificate, it gives an error saying the renewal failed. Could this be due to nginx acting as a reverse proxy? I have set up the reverse proxy exactly as described here and am calling my node app which listens to a localhost port as shown in this tutorial. This is the error I am getting: produced an unexpected error: Problem binding to port 443: Could not bind to IPv4 or IPv6.. Skipping."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I have an NGINX PHP (WordPress) site in the root and I want to have a Node.js app (Meteor, Angular2, MongoDB) at https://mydomain.com/nodeapp How shall the NGINX /etc/nginx/sites-enabled/digitalocean file look like? (I installed using the DigitalOcean UBUNTU 16.04 LEMP image, that’s why the config file is called digitalocean…)"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I’m getting a.... The mydomain.com page isn’t working. mydomain.com redirected you too many times. ERRTOOMANY_REDIRECTS Could anyone think of a reason why this would be happening? I followed the tutorial very closely. The only thing that I could think that may be causing an error are my subdomains. I can give more information."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"need update for ES6 with PM2."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I followed the guide but some how response from nginx proxy reverse is wrapped in \\u003cpre\\u003e tags. But when i access the droplet ip with the port to node app is working fine."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"what if there is Apache server already installed ? can both install (Apache and NginX) at one server providing two applications such as Apache for HTML/PHP based application and nGinx for Node JS application ? Thanks"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hi, thanks for great tutorial! Is it possible to run separate node apps on different routes, using SSL? If no can you guys tell me, how can i disable non https redirect to https? thanks!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I followed this tutorial to setup node react app, but it take 20 sec to load a page which should be very less, What configuration need to change in order to load page normally?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"How would you setup a ssl certificate both for www.mydomain.com and mydomain.com using SAN?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"should “https://deb.nodesource.com/setup_6.x” now be updated to “https://deb.nodesource.com/setup_9.x” ? 6.x is no longer the newest version of node"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"To deploy the easy way with a single command to your digitalocean droplet, you could use a tool like OpsCaptain. OpsCaptain brings the PaaS experience to your own server. No need to fiddle with bash scripts and maintain them. Simply connect your droplet and upload your project from the dashboard or run [opscaptain deploy]. It is that easy to deploy to your droplet. https://www.opscaptain.com/nodejs-hosting"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Output [PM2] Init System found: systemd [PM2] You have to run this command as root. Execute the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy –hp /home/sammy I don’t see any of this? Why?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"#!/usr/bin/env nodejs var http = require(\'http\'); http.createServer(function (req, res) { res.writeHead(200, {\'Content-Type\': \'text/plain\'}); res.end(\'Hello World\\\\n\'); }).listen(8080, \'localhost\'); console.log(\'Server running at http://localhost:8080/\'); I absolutely cannot get this code to work. I literally followed the whole tutorial step-by-step, and after adding this “hello.js” file and making it executable, it simply doesn’t work. It starts up and displays the console log, but when I try to visit it (or curl it) it doesn’t load. Any idea? I’ve been at this for the past two hours and I’m about to go insane."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"502 Bad Gateway"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Your tutorial is awesome! Thank you for helping us!"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Turns out when installing and configuring pm2 IT IS ABSOLUTELY IMPERATIVE that to execute none of those commands as root AND that you do NOT use sudo in any of the commands where sudo is not shown in the article. D.O support might advise you otherwise. But take my word for it. To not most likely will drive you mad."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"How can I expose another Express app on another port publicly? (i.e. one express app running on port 8080 is served publicly on port 80, while a second express app running on port 8081 is served publicly on port 8008) In my /etc/nginx/sites-available/default file I added the following server block directly after the 443 ssl server. server { listen 8008 ssl; server_name example.com www.example.com; include snippets/ssl-example.com.conf; include snippets/ssl-params.conf; # pass requests to port 8081 where our other node server is running 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:8081/; proxy_ssl_session_reuse off; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_redirect off; } } Currently, all public traffic (http or https) to port 8008 results in a timeout. Hitting the app locally over https (i.e. https://example.com:8008) results in a success response, while hitting the app locally over http (i.e. http://example.com:8008) results in 400 The plain HTTP request was sent to HTTPS port. The desired behavior is that all public http traffic continues to be redirected to https, and the second express app is available publicly at https://example.com:8008. I’ve been wrestling with this for over a day now. Any help or guidance would be much appreciated! :)"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"When using nginx as a reverse proxy with http2, is it advisable to use spdy npm on the node/express end as well? Or is it better to leave that on http behind the scenes?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"This just doesn’t work. No change after modifying location."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Great article! Never thought it’s that easy to host multiple node apps on one droplet. Just one nitpick, there should be a trailing / for the line in /etc/nginx/sites-available/default file. Without it, I was getting 404’s from my apps. proxy_pass http://localhost:8081/;"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Great tutorial! I want to try out the nginx function, config my location block to location /app2 { ... }, then browse my website by domain.com/app2. Turns out nodejs return “Cannot GET /app2”. It works if just location / { ... }. I am new to nodejs \\u0026 nginx, can anyone tell me what is happening?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Thanks for this excellent article "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"I was receiving 404 errors until I appended a / after the proxy_pass value. proxy_pass http://localhost:8081/;"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"It would be nice to have some reference to the tutorial about setting up server blocks. I’m using nginx as a reverse proxy so I can run several websites from one droplet. Adding something like: “if you have set up multiple server block virtual hosts you can replace the location block in each file created in the sites-available directory with location / { proxy_pass http://localhost: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; } Be sure to change 8080 to the port of each node process"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Why pm2? Any chances to use forever?"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"how to setup server blocks with nodejs app as root with wordpress as child? location /{ } location /blog{ } tnx..x :|"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"please add info about doing a proxy with socket.io included! "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"From what I’m reading elsewhere, PM2 has been made rather redundant due to the presence of systemd on these newer linux distros. See http://stackoverflow.com/questions/4018154/node-js-as-a-background-service"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Hello everyone, My name is Q, I’m now a developer for my site. I use 1 droplet 5$ for MongoDB and 1 for Nodejs(API service) The issue here is when i deploy my Node app( all the steps before deploying are done with no errors) using PM2( the PM2 listed app as online and command curl to the ip:port of app works just fine) the app cant be reached by browser Link: 128.199.177.41:3001/apis/…( run at port 3001, … could be /accounts/verify which get a JSON msg) Please help me! Thank you in advance! P/s: Previously, I have my old server(also 5$ droplet on Digital Ocean) running just fine"}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"While setting up the reverse proxy using localhost: proxy_pass http://localhost:8080; It sometimes spits out a 502 error. This may happen due an infinite loop of domain forwarding. To avoid this, use ip address instead of localhost or 127.0.0.1 like as follows. proxy_pass http://255.255.255.255:8080; replace 255.255.255.255 by your external ip address Also, if you need to point this to a subdomain instead of main domain or any directory path: server { listen 80; server_name SUBDOMAIN.DOMAIN.com; location / { proxy_pass http://IP_ADDRESS:8080; //ip address or localhost or domain name. Make sure it doesn’t fall in an infinite loop of redirects. IP address is safest option but it’s a situational thing 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; } } "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"Thanks for such a great blog. PM2 is marvellous. my sockets use to hang up for some reason and node went down. PM2 takes care of that. Can you tell me where I can see the logs? I have a few console.log I would like to track. It would be nice to reset the logs every 24 hours as well. thanks "}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"thank you vary much , this tutorial is very easy to a newer to learn ,这个网站的很多教程都写的非常棒!hope one day i can give a tutorial like this ."}},{"comment":{"@context":"http://schema.org","@type":"Comment","text":"While checking in browser of my local machine, i am getting error like connection refused"}}]}. $(function() {. $(\'.use-universal-search-js\').on(\'click\', function () {. $(\'#q\').trigger(\'click\');. });. });. window.loadUniversalSearchScript( function () {. var search = new UniversalSearch({. element_id: \'q\',. search_on_slash: true,. primary_list: [\'quicknav\', \'community_consolidated\'],. secondary_list: [\'alldocs\', \'marketplace\'],. algolia_app_id: "6ZHEUVKJ88",. algolia_public_key: "c5470567eae7fa1177d43222e18ba086". });. search.start();. });.',
    description:
      "Node.js is an open source JavaScript runtime environment for easily building server-side and networking applications. Node.js applications can be run at the command line but this guide focuses on running them as a service using PM2, so that they will",
    lang: "en",
    canonicalLink:
      "https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04",
    tags: ["Nginx", "Node.js", "Let's Encrypt", "Ubuntu 16.04"],
    image:
      "https://www.digitalocean.com/assets/community/illustrations/DigitalOcean_Community-e00e73a18df20667c3117725e727f3ade330204dff619ad8153050ded7341627.jpg",
    videos: [],
    links: [
      {
        text: "NodeSource",
        href: "https://github.com/nodesource/distributions"
      },
      {
        text:
          "Systemd Essentials: Working with Services, Units, and the Journal",
        href:
          "https://www.digitalocean.com/community/tutorials/systemd-essentials-working-with-services-units-and-the-journal"
      }
    ],
    text:
      "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. Node.js applications can be run at the command line, but we’ll focus on running them as a service, so that they will automatically restart on reboot or failure, and can safely be used in a production environment.\n\nIn this tutorial, we will cover setting up a production-ready Node.js environment on a single Ubuntu 16.04 server.  This server will run a Node.js application managed by PM2, and provide users with secure access to the application through an Nginx reverse proxy.  The Nginx server will offer HTTPS, using a free certificate provided by Let’s Encrypt.\n\nThis guide assumes that you have the following:\n\nWhen you’ve completed the prerequisites you will have a server serving the default Nginx placeholder page at https://example.com/.\n\nLet’s get started by installing the Node.js runtime on your server.\n\nWe will install the latest LTS release of Node.js, using the NodeSource package archives.\n\nFirst, you need to install the NodeSource PPA in order to get access to its contents.  Make sure you’re in your home directory, and use curl to retrieve the installation script for the Node.js 6.x archives:\n\ncd ~\n\ncurl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh\n\nYou can inspect the contents of this script with nano (or your preferred text editor):\n\nnano nodesource_setup.sh\n\nAnd run the script under sudo:\n\nsudo bash nodesource_setup.sh\n\nThe PPA will be added to your configuration and your local package cache will be updated automatically. After running the setup script from nodesource, you can install the Node.js package in the same way that you did above:\n\nsudo apt-get install nodejs\n\nThe nodejs package contains the nodejs binary as well as npm, so you don’t need to install npm separately. However, in order for some npm packages to work (such as those that require compiling code from source), you will need to install the build-essential package:\n\nsudo apt-get install build-essential\n\nThe Node.js runtime is now installed, and ready to run an application! Let’s write a Node.js application.\n\nNote: When installing from the NodeSource PPA, the Node.js executable is called nodejs, rather than node.\n\nWe will write 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 with your own application–just make sure that you modify your application to listen on the appropriate IP addresses and ports.\n\nFirst, create and open your Node.js application for editing. For this tutorial, we will use nano to edit a sample application called hello.js:\n\ncd ~\n\nnano hello.js\n\nInsert the following code into the file.  If you want to, you may replace the highlighted port, 8080, in both locations (be sure to use a non-admin port, i.e. 1024 or greater):\n\n#!/usr/bin/env nodejs\n\nvar http = require('http');\n\nhttp.createServer(function (req, res) {\n\nres.writeHead(200, {'Content-Type': 'text/plain'});\n\nres.end('Hello World\\n');\n\n}).listen(8080, 'localhost');\n\nconsole.log('Server running at http://localhost:8080/');\n\nThis Node.js application simply listens on the specified address (localhost) and port (8080), and returns “Hello World” with a 200 HTTP success code. Since we’re listening on localhost, remote clients won’t be able to connect to our application.\n\nIn order to test your application, mark hello.js executable:\n\nchmod +x ./hello.js\n\nAnd run it like so:\n\n./hello.js\n\nOutputServer running at http://localhost:8080/\n\nNote: Running a Node.js application in this manner will block additional commands until the application is killed by pressing Ctrl-C.\n\nIn order to test the application, open another terminal session on your server, and connect to localhost with curl:\n\ncurl http://localhost:8080\n\nIf you see the following output, the application is working properly and listening on the proper address and port:\n\nOutputHello World\n\nIf you do not see the proper output, make sure that your Node.js application is running, and configured to listen on the proper address and port.\n\nOnce you’re sure it’s working, kill the application (if you haven’t already) by pressing Ctrl+C.\n\nNow 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 in the background as a service).\n\nWe will use npm, a package manager for Node modules that installs with Node.js, to install PM2 on our server. Use this command to install PM2:\n\nsudo npm install -g pm2\n\nThe -g option tells npm to install the module globally, so that it’s available system-wide.\n\nPM2 is simple and easy to use. We will cover a few basic uses of PM2.\n\nThe first thing you will want to do is use the pm2 start command to run your application, hello.js, in the background:\n\npm2 start hello.js\n\nThis also adds your application to PM2’s process list, which is outputted every time you start an application:\n\nOutput[PM2] Spawning PM2 daemon\n\n[PM2] PM2 Successfully daemonized\n\n[PM2] Starting hello.js in fork_mode (1 instance)\n\n[PM2] Done.\n\n│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ memory      │ watching │\n\n│ hello    │ 0  │ fork │ 3524 │ online │ 0       │ 0s     │ 21.566 MB   │ disabled │\n\nUse `pm2 show\n\nAs 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.\n\nApplications 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.\n\nThe startup subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots:\n\npm2 startup systemd\n\nThe last line of the resulting output will include a command that you must run with superuser privileges:\n\nOutput[PM2] Init System found: systemd\n\n[PM2] You have to run this command as root. Execute the following command:\n\nsudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy\n\nRun the command that was generated (similar to the highlighted output above, but with your username instead of sammy) to set PM2 up to start on boot (use the command from your own output):\n\nsudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy\n\nThis will create a systemd unit which runs pm2 for your user on boot.  This pm2 instance, in turn, runs hello.js.  You can check the status of the systemd unit with systemctl:\n\nsystemctl status pm2-sammy\n\nFor a detailed overview of systemd, see Systemd Essentials: Working with Services, Units, and the Journal.\n\nPM2 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.\n\nStop an application with this command (specify the PM2 App name or id):\n\npm2 stop app_name_or_id\n\nRestart an application with this command (specify the PM2 App name or id):\n\npm2 restart app_name_or_id\n\nThe list of applications currently managed by PM2 can also be looked up with the list subcommand:\n\npm2 list\n\nMore information about a specific application can be found by using the info subcommand (specify the PM2 App name or id):\n\npm2 info example\n\nThe PM2 process monitor can be pulled up with the monit subcommand. This displays the application status, CPU, and memory usage:\n\npm2 monit\n\nNow that your Node.js application is running, and managed by PM2, let’s set up the reverse proxy.\n\nNow that your application is running, and listening on localhost, you need to set up a way for your users to access it. We will set up the Nginx web server as a reverse proxy for this purpose.\n\nIn the prerequisite tutorial, we set up our Nginx configuration in the /etc/nginx/sites-available/default file. Open the file for editing:\n\nsudo nano /etc/nginx/sites-available/default\n\nWithin the server block you should have an existing location / block. Replace the contents of that block with the following configuration. If your application is set to listen on a different port, update the highlighted portion to the correct port number.\n\nlocation / {\n\nproxy_pass http://localhost:8080;\n\nproxy_http_version 1.1;\n\nproxy_set_header Upgrade $http_upgrade;\n\nproxy_set_header Connection 'upgrade';\n\nproxy_set_header Host $host;\n\nproxy_cache_bypass $http_upgrade;\n\nThis configures the server to respond to requests at its root. Assuming our server is available at example.com, accessing https://example.com/ via a web browser would send the request to hello.js, listening on port 8080 at localhost.\n\nYou can add additional location blocks to the same server block to provide access to other applications on the same server. For example, if you were also running another Node.js application on port 8081, you could add this location block to allow access to it via http://example.com/app2:\n\nlocation /app2 {\n\nproxy_pass http://localhost:8081;\n\nproxy_http_version 1.1;\n\nproxy_set_header Upgrade $http_upgrade;\n\nproxy_set_header Connection 'upgrade';\n\nproxy_set_header Host $host;\n\nproxy_cache_bypass $http_upgrade;\n\nOnce you are done adding the location blocks for your applications, save and exit.\n\nMake sure you didn’t introduce any syntax errors by typing:\n\nsudo nginx -t\n\nsudo systemctl restart nginx\n\nAssuming that your Node.js application is running, and your application and Nginx configurations are correct, you should now be able to access your application via the Nginx reverse proxy. Try it out by accessing your server’s URL (its public IP address or domain name).\n\nCongratulations! You now have your Node.js application running behind an Nginx reverse proxy on an Ubuntu 16.04 server. 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!"
  }
};