Deploy a Meteor App to Digital Ocean in 8 Steps — Ubuntu 14.04

If you type quick.

We will be using Phusion Passenger.

Scroll down if you want to skip to the tutorial

Bulid : Ubuntu 14.04

Host : Digital Ocean

Phusion Passenger™ is an open source, polyglot (multi-language) application server. It takes a lot of complexity out of deploying Meteor, and adds powerful enterprise-grade features that are useful in production. It also makes it administering Meteor apps much easier. It has already done this for Ruby, Python and Node.js, and is being used by high-profile companies such as Apple, Pixar, New York Times, AirBnB, Juniper etc as well as over 350.000 websites.

Why use Meteor on Passenger?

Here are some of the benefits that you will gain:

The power of Nginx
Phusion Passenger combines Meteor with the increasingly popular Nginx web server. By combining them, Nginx will offload Meteor from serving static assets. This also adds a buffering reverse proxy layer which provides I/O security and protects Meteor against invalid HTTP requests, slow clients, etc. It will even allow you to use SSL without having to code explicit SSL support in your Node app.

Nginx isn’t the only thing supported though. Passenger also supports Apache, and can even run standalone without needing an existing web server.

Multitenancy
Run multiple Meteor applications on a single server easily and without hassle.

Process management and supervision
Meteor processes are automatically started, and automatically restarted when they crash.

Statistics and insight
Phusion Passenger provides tools for inspecting the applications’ status, such what requests they’re currently processing, how many requests they’ve processed.

Scaling and load balancing
Based on current traffic, Phusion Passenger can spawn more Meteor processes to handle the load, or spin down some existing Meteor processes to conserve resources. Phusion Passenger automatically load balances traffic across Meteor processes. The load balancing mechanism utilizes a smart “first-available” selection algorithm to avoid problems caused by slow requests. Although Node.js — and thus Meteor — is single-threaded, this approach allows you to utilize multiple CPU cores.

I/O security
Meteor is automatically put behind a buffering web server, such as Nginx or Apache, which preprocesses and postprocesses HTTP requests and responses. This protects the Meteor app against slow-client attacks such as Slowloris. It also provides a secure environment which sanitizes HTTP headers, to protect against vulnerabilities in the app’s HTTP parser.

System security
Meteor processes are automatically started as the user which owns the app. This allows the OS to separate their privileges, so that a vulnerability in one app does not affect another.

Static file acceleration
Static files are directly served by the web server (Nginx/Apache), not by Meteor. This offloads the Meteor application from handling those things.

How does Passenger work?


Now the step-by-step instructions to bring your Meteor to life!

This is an end-to-end walkthrough that teaches you how to install Meteor and Passenger on a production server. This walkthrough will ask you some questions, so the exact walkthrough steps depend on the choices you make. In general, it covers these topics:

STEP 1 — Install Node.js

Login via ssh to your Ubuntu/Debian Server.

$ sudo apt-get update
$ sudo apt-get install -y curl apt-transport-https ca-certificates &&
curl --fail -ssL -o setup-nodejs https://deb.nodesource.com/setup_0.12 &&
sudo bash setup-nodejs &&
$ sudo apt-get install -y nodejs build-essential

STEP 2 — Install Passenger

These commands will install Passenger + Nginx through Phusion’s APT repository. If you already had Nginx installed, then these commands will upgrade Nginx to Phusion’s version (with Passenger compiled in).

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
$ sudo apt-get install -y apt-transport-https ca-certificates

# Add our APT repository
$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main > /etc/apt/sources.list.d/passenger.list'
$ sudo apt-get update

# Install Passenger + Nginx
$ sudo apt-get install -y nginx-extras passenger

STEP 3—Enable Passenger

$ Nano /etc/nginx/nginx.conf

Then, uncomment passenger_root and passenger_ruby. For example, you may see this:

# passenger_root /some-filename/locations.ini;
# passenger_ruby /usr/bin/passenger_free_ruby;

remove the “# ” characters like this

passenger_root /some-filename/locations.ini;
passenger_ruby /usr/bin/passenger_free_ruby;

restart nginx

$ sudo service nginx restart

STEP 4— Build a meteor bundle of your app

Head to your Meteor Project Directory/Folder and run

$ meteor bundle package.tar.gz
Meteor will probably tell you that meteor bundle is deprecated in favor of meteor build. Please ignore that message, because for the purpose of running a Meteor web application on Passenger, only `meteor bundle` does what we want.

Copy the package to your production server, for example using scp:

local-computer$ scp package.tar.gz adminuser@yourserver.com:~

Login to your server with SSH and create a user for your app.

$ ssh adminuser@yourserver.com

Replace adminuser with the name of an account with administrator privileges or sudo privileges.

STEP 5— Upload package to server

Starting from this point, unless stated otherwise, all commands that we instruct you to run should be run on the server, not on your local computer!

Now that you have logged in, you should create an operating system user account for your app. For security reasons, it is a good idea to run each app under its own user account, in order to limit the damage that security vulnerabilities in the app can do. Passenger will automatically run your app under this user account as part of its user account sandboxing feature.

You should give the user account the same name as your app. But for demonstration purposes, this tutorial names the user account myappuser.

$ sudo adduser myappuser

Make sure the user has your SSH key installed:

$ sudo mkdir -p ~myappuser/.ssh
$ sudo sh -c "cat $HOME/.ssh/authorized_keys >> ~myappuser/.ssh/authorized_keys"
$ sudo chown -R myappuser: ~myappuser/.ssh
$ sudo chmod 700 ~myappuser/.ssh
$ sudo sh -c "chmod 600 ~myappuser/.ssh/*"

Now, extract your package to a permanent location on your server.

A good location is/var/www/APP_NAME. Let us create that directory.

$ sudo mkdir -p /var/www/myapp
$ cd /var/www/myapp
$ tar xzf ~/package.tar.gz
$ chown -R myappuser: .

Your extract app package directory now lives on the server at /var/www/myapp/bundle.

STEP 6 — Preparing the app’s environment

Install MongoDB

$ sudo apt-get install -y mongodb

Login as the app’s user

$ sudo -u myappuser -H bash -l

Install app dependencies

$ cd /var/www/myapp/bundle/programs/server
$ npm install --production

Step 7 — Configuring Nginx and Passenger

Go back to the admin account

Example:

# Type `exit` to go back to the account you were before
myappuser$ exit
admin$ _

Edit Nginx configuration file

$ sudo nano /etc/nginx/sites-enabled/myapp.conf
Remember to replace myapp to your app’s name

Put this inside the file:

server {
listen 80;
server_name yourserver.com;

# Tell Nginx and Passenger where your app's 'public' directory is
root /var/www/myapp/bundle/public;

# Turn on Passenger
passenger_enabled on;
# Tell Passenger that your app is a Meteor app
passenger_app_type node;
passenger_startup_file main.js;

# Tell your app where MongoDB is
passenger_env_var MONGO_URL mongodb://localhost:27017/myappdb;
# Tell your app what its root URL is
passenger_env_var ROOT_URL http://yourserver.com;
}
Replace yourserver.com with your server’s host name and replace /var/www/myapp/bundle with your application’s package directory path. Replace myappdb with an appropriate MongoDB database name. Also be sure to set ROOT_URL to an appropriate value.

Restart nginx

$ sudo service nginx restart

Step 8 — Test!

You should now be able to access your app through the server’s host name! Try running this from your local computer. Replace yourserver.com with your server’s hostname, exactly as it appears in the Nginx config file’s server_name directive.

$ curl http://yourserver.com/

If you do not see your app’s front page HTML, then these are the most likely causes:

  1. You did not correctly configure your server_name directive. The server_name must exactly match the host name in the URL. For example, if you use the command curl http://45.55.91.235/ to access your app, then the server_name must be 45.55.91.235.
  2. You did not setup DNS records. Setting up DNS is outside the scope of this walkthrough. In the mean time, we recommend that you use your server’s IP address as the server name.

Congratulations, you have successfully deployed your Meteor app on to Digital Ocean.


Deploying Updates — Transferring latest code

Build and upload new package

Inside your application’s code directory, on your local computer, use the meteor bundle command to create a Meteor package tarball of the latest application code.

local-computer$ meteor bundle package.tar.gz

Copy the package to your production server, for example using scp:

local-computer$ scp package.tar.gz myappuser@yourserver.com:

Replace myappuser with name of the application’s OS user account.

Login to the server as the application’s user

Login to your server with SSH:

local-computer$ ssh myappuser@yourserver.com

Replace myappuser with name of the application’s OS user account.

Starting from this point, unless stated otherwise, all commands that we instruct you to run should be run on the server, not on your local computer!

Extract package

Extract the package to a temporary location, for example /var/www/yourapp/tmp.

$ mkdir -p /var/www/myapp/tmp
$ cd /var/www/myapp/tmp
$ tar xzf ~/package.tar.gz

Replace myapp and myappuser with your app’s name and your app user account’s name.

The extracted package is now located in /var/www/myapp/tmp/bundle.

Prepare application

Install app dependencies

Your application’s npm dependencies may have changed, so we should install any updated npm dependencies while removing any now-extraneous dependencies. Run:

$ cd /var/www/myapp/tmp/bundle/programs/server
$ npm install --production
$ npm prune --production

Activate application updates

Passenger may still be serving an old instance of your application. Now that all application updates have been prepared, it is time to activate the newly uploaded application package.

Rename the old application directory to something different, and move the new application directory to where the old application directory was:

$ mv /var/www/myapp/bundle /var/www/myapp/bundle.old
$ mv /var/www/myapp/tmp/bundle /var/www/myapp/bundle

Tell Passenger to restart the application so that the updates take effect.

$ passenger-config restart-app /var/www/myapp/bundle

Wait a few seconds (for Passenger to do its job), then remove the old application directory:

$ rm -rf /var/www/myapp/bundle.old

Congratulations! You did it!

Now to celebrate, spread the Meteor!

Sourced from Phusion Passenger and Various other Tutorials and Guides.

More Stuff!!!