Deploy Node.js application using Passenger on Dreamhost or other hosting providers

By: ( +David Herron; Date: Sun Jan 07 2018 16:00:00 GMT-0800 (Pacific Standard Time)

Tags: Node.js

On regular web hosting PHP rules the world, and you might think Node.js has no chance. I haven't cross-checked among current web hosting providers, but Dreamhost does offer the option of hosting Ruby or Node.js applications on a VPS using Passenger. In case you've never heard of Passenger, it is an "app server" for hosting Ruby, Python or Node.js applications. Dreamhost supports all three, but for our purpose we're interested in using this to run a Node.js app.

The process is fairly simple, but Dreamhost somehow managed to make their documentation confusing enough to warrant a blog post. See links below for official documentation.

These instructions are for Dreamhost. It is possible other hosting providers offer a similar capability. Do not try to set up Node.js anything on Dreamhost shared hosting. According to their Wiki, Dreamhosts' security scanning scripts will detect the attempt to compile Node.js and lock your account. Don't do that.

These instructions are for a Dreamhost VPS. The kind which is managed by the Dreamhost control panel. If instead you have a Dreamhost Cloud server, that's a regular plain vanilla operating system installation on which you use normal mechanisms to host Node.js (or other) code.

After logging into the Dreamhost control panel, go to Manage Domains and click on the Add Hosting to a Domain / Subdomain button. This is presuming you'll be adding a new domain, or subdomain, and using that domain to set up Node.js support. Perhaps instead you're interested in adding Node.js to an existing domain in which case you'll be following a slightly different process.

You'll see this screen - which should be familiar if you've done much web hosting on Dreamhost.

Configuration settings to use Node.js on Dreamhost

The annotations in the image are fairly straight-forward. But let's walk through it step by step.

First - select the username under which the application will be hosted. Remember that Dreamhost associates domains to usernames, and the username is then associated with a host on which the domain(s) are hosted. Some usernames are associated with VPS's, and as said above Node.js app's must be hosted on a VPS.

Then go down to the Passenger choice, and enable that button. A pair of buttons will show up letting you select either Ruby or Node.js support. Select Node.js.

A question will pop up saying the web directory must end in /public. Click the OK button to that. We'll discuss it in a minute.

That's the control panel configuration finished - you can do whatever you wish about PHP support. Click the button to go ahead and create the domain. The happy Dreamhost robot thingy will tell you it'll take 5-10 minutes to get that set up, and some amount of other time for the domain name to propagate. We have a couple things for you to do while you're waiting.

Node.js version The default version of Node.js is very old:

$ /usr/bin/node  --version

It's easy (and recommended) to install nvm to manage Node.js installation, see: ( Once installed using an up-to-date release is this easy:

$ nvm install 8
v8.9.4 is already installed.
Now using node v8.9.4 (npm v5.6.0)
$ which node

But the next step is to ensure Passenger knows to use this Node.js release. That's done in the .htaccess as so:

$ cat /home/USERNAME/DOMAIN.COM/public/.htaccess 
PassengerNodejs /home/USERNAME/.nvm/versions/node/v8.9.4/bin/node

We now need to explain a bit about the public directory which was appended to the web directory. It's this directory which Apache will see as the webroot for the domain name. Any request for http://DOMAIN.COM/example.html (or anything else) will be interpreted relative to this directory. To prove it create /home/USERNAME/DOMAIN.COM/public/phpinfo.php containing the following:

<? phpinfo(); ?>

Then visit http://DOMAIN.COM/phpinfo.php and see that it works. Ergo, the public directory is the webroot for the domain. That makes the .htaccess file a normal Apache thing which you can use to do normal Apache .htaccess things.

What's up with this? We proved you can install PHP, and this is supposed to be about Node.js. Patience my friend... We needed to show you the public directory, and how to use it.

The next thing is to install a Node.js application. Let's just borrow one from the Node.js website:

$ cat /home/USERNAME/DOMAIN.COM/app.js 
var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");

The Passenger runtime will look for app.js as the entry point for the application. Write your code accordingly. This app is listing on port #80 so it will be accessible as: `http://DOMAIN.COM/' on the bare domain.

This is as far as I've tested.

If you're using Express let's consider how to mount static assets. Clearly from the phpinfo.php example files in the public directory will be automatically handled by Apache. That's a good thing because Apache will serve those files much more quickly than the Node.js app, and it removes overhead from the Node.js code.

Therefore, this line of code is unneeded:

// app.use(express.static(path.join(__dirname, 'public')));

Another typical thing is to host Bootstrap, jQuery and other front-end assets as Node.js modules in the node_modules directory. For that purpose the following statements are used in an Express app.js:

app.use('/assets/vendor/bootstrap', express.static( 
  path.join(__dirname, 'node_modules', 'bootstrap', 'dist'))); 
app.use('/assets/vendor/jquery', express.static( 
  path.join(__dirname, 'node_modules', 'jquery'))); 
app.use('/assets/vendor/popper.js', express.static( 
  path.join(__dirname, 'node_modules', 'popper.js', 'dist')));  
app.use('/assets/vendor/feather-icons', express.static( 
  path.join(__dirname, 'node_modules', 'feather-icons', 'dist'))); 

While this will work, it means Express is responsible for serving those files. As we just said, it'll be less overhead to let Apache serve those files. You might want to spend the time to work out how to deploy those files into the public directory so Apache can do so.

It's your choice whether to serve static files through Express or via Apache. There are legitimate reasons to do it either way. It boils down this way:

  1. Any file that must be delivered unmodifed should be (but doesn't have to be) delivered directly by Apache.
  2. Any file that must be modified must be delivered by Node.js code.

How to deploy? The script we showed earlier is simple enough to edit on the server. But the typical thing will require something more. As I've not gone through that let me suggest the following untested idea:

  1. Use git to deploy code on a server ...
    • e.g. npm install USERNAME/PROJECT-NAME to deploy from a github repository, or else npm install http://GIT-HOST.COM/PATH/TO/TARBALL.tar to deploy from a tarball.
    • In my case, I have a GOGS server (github clone) for personal repositories. I can test the code on my laptop, and push to the GOGS server. That server exports tarball URL's that can be used as shown here.
  2. On the server, use npm install (as just shown) to install all dependencies
  3. Work out how to separate the static assets which should be delivered with Apache into the public directory


« Loading an ES6 module in a CommonJS module using require() Automating Node.js/JavaScript code quality checks with eslint »
2016 Election 2018 Elections Acer C720 Ad block Affiliate marketing Air Filters Air Quality Air Quality Monitoring AkashaCMS Amazon Amazon Kindle Amazon Web Services America Amiga and Jon Pertwee Android Anti-Fascism AntiVirus Software Apple Apple Flexgate Apple Hardware History Apple Hardware Mistakes Apple iPhone Apple iPhone Hardware April 1st Arduino ARM Compilation Artificial Intelligence Astronomy Astrophotography Asynchronous Programming Authoritarianism Automated Social Posting AWS DynamoDB AWS Lambda Ayo.JS Bells Law Big Brother Big Data Big Finish Big Science Bitcoin Mining Black Holes Blade Runner Blockchain Blogger Blogging Books Botnets Cassette Tapes Cellphones China China Manufacturing Christopher Eccleston Chrome Chrome Apps Chromebook Chromebox ChromeOS CIA CitiCards Citizen Journalism Civil Liberties Climate Change Clinton Cluster Computing Command Line Tools Comment Systems Computer Accessories Computer Hardware Computer Repair Computers Conservatives Cross Compilation Crouton Cryptocurrency Curiosity Rover Currencies Cyber Security Cybermen Cybersecurity Daleks Darth Vader Data backup Data Formats Data Storage Database Database Backup Databases David Tenant DDoS Botnet Department of Defense Department of Justice Detect Adblocker Developers Editors Digital audio Digital Nomad Digital Photography Direct Attach Storage Diskless Booting Disqus DIY DIY Repair DNP3 Do it yourself Docker Docker MAMP Docker Swarm Doctor Who Doctor Who Paradox Doctor Who Review Drobo Drupal Drupal Themes DuckDuckGo DVD E-Books E-Readers Early Computers eGPU Election Hacks Electric Bicycles Electric Vehicles Electron Eliminating Jobs for Human Emdebian Encabulators Energy Efficiency Enterprise Node EPUB ESP8266 Ethical Curation Eurovision Event Driven Asynchronous Express Face Recognition Facebook Fake Advertising Fake News Fedora VirtualBox Fifth Doctor File transfer without iTunes FireFly Flash Flickr Fraud Freedom of Speech Front-end Development G Suite Gallifrey Gig Economy git Github GitKraken Gitlab GMAIL Google Google Adsense Google Chrome Google Gnome Google+ Government Spying Great Britain Green Transportation Hate Speech Heat Loss Hibernate High Technology Hoax Science Home Automation HTTP Security HTTPS Human ID I2C Protocol Image Analysis Image Conversion Image Processing ImageMagick In-memory Computing Incognito Mode InfluxDB Infrared Thermometers Insulation Internet Internet Advertising Internet Law Internet of Things Internet Policy Internet Privacy iOS iOS Devices iPad iPhone iPhone hacking Iron Man iShowU Audio Capture iTunes Janet Fielding Java JavaFX JavaScript JavaScript Injection JDBC John Simms Journalism Joyent jQuery Kaspersky Labs Kext Kindle Kindle Marketplace Large Hadron Collider Lets Encrypt LibreOffice Linux Linux Hints Linux Single Board Computers Logging Mac Mini Mac OS Mac OS X Mac Pro MacBook Pro Machine Learning Machine Readable ID Macintosh macOS macOS High Sierra macOS Kext MacOS X setup Make Money Online Make Money with Gigs March For Our Lives MariaDB Mars Mass Violence Matt Lucas MEADS Anti-Missile Mercurial MERN Stack Michele Gomez Micro Apartments Microsoft Military AI Military Hardware Minification Minimized CSS Minimized HTML Minimized JavaScript Missy Mobile Applications Mobile Computers MODBUS Mondas Monetary System MongoDB Mongoose Monty Python MQTT Music Player Music Streaming MySQL NanoPi Nardole NASA Net Neutrality Network Attached Storage Node Web Development Node.js Node.js Database Node.js Performance Node.js Testing Node.JS Web Development Node.x North Korea npm NSA NVIDIA NY Times Online advertising Online Community Online Fraud Online Journalism Online News Online Photography Online Video Open Media Vault Open Source Open Source and Patents Open Source Governance Open Source Licenses Open Source Software OpenAPI OpenJDK OpenVPN Palmtop PDA Patrick Troughton PayPal Paywalls Personal Flight Peter Capaldi Peter Davison Phishing Photography PHP Plex Plex Media Server Political Protest Politics Postal Service Power Control President Trump Privacy Private E-mail server Production use Public Violence Raspberry Pi Raspberry Pi 3 Raspberry Pi Zero ReactJS Recaptcha Recycling Refurbished Computers Remote Desktop Removable Storage Renewable Energy Republicans Retro Computing Retro-Technology Reviews RFID Rich Internet Applications Right to Repair River Song Robotics Robots Rocket Ships RSS News Readers rsync Russia Russia Troll Factory Russian Hacking Rust SCADA Scheme Science Fiction SD Cards Search Engine Ranking Search Engines Season 1 Season 10 Season 11 Security Security Cameras Server-side JavaScript Serverless Framework Servers Shell Scripts Silence Simsimi Skype SmugMug Social Media Social Media Networks Social Media Warfare Social Network Management Social Networks Software Development Software Patents Space Flight Space Ship Reuse Space Ships SpaceX Spear Phishing Spring Spring Boot Spy Satellites SQLite3 SSD Drives SSD upgrade SSH SSH Key SSL Stand For Truth Strange Parts Swagger Synchronizing Files Tegan Jovanka Telescopes Terrorism The Cybermen The Daleks The Master Time-Series Database Tom Baker Torchwood Total Information Awareness Trump Trump Administration Trump Campaign Twitter Ubuntu Udemy UDOO US Department of Defense Video editing Virtual Private Networks VirtualBox VLC VNC VOIP Vue.js Walmart Weapons Systems Web Applications Web Developer Resources Web Development Web Development Tools Web Marketing Webpack Website Advertising Website Business Models Weeping Angels WhatsApp William Hartnell Window Insulation Windows Windows Alternatives Wordpress World Wide Web Yahoo YouTube YouTube Adpocalypse YouTube Monetization