/ meteor

Hosting multiple instances of Meteor on DigitalOcean

UPDATE: As Galaxy is out and Meteor Up is not being actively developed I'd suggest you save your headaches and just go with Galaxy.

As per request, here is how I’ve made my server managing with Meteor.js easy.

I’ve got a more than 6 instances of Meteor running on a single droplet in DigitalOcean ($5 a month is damn cheap for such a great service). Meteor Up starts and keeps the service alive even after system reboot and Nginx for the connecting apps to real users.

For this example I’m going to use my latest app — Movie at My Place (check out this example event to get a better idea what it’s about).

DigitalOcean

Create a droplet from the "Node on Ubuntu" image, under Create > Select image > Applications. This way you've got Node and some other useful stuff preinstalled.

You’ve also got to register a domain somewhere else and configure the DNS in DigitalOcean.

Meteor Up

Install Mup with npm install -g mup (more information)

MUp requires a seperate folder with its setting files for each project. I’ve got my website files in /srv/MovieAtMyPlace/ and my Meteor Up files in /srv/movieatmyplace_deployment/, so all my files are in one place and it’s clear what each folder is for (lowercase helps with quickly changing directories).

Settings.json is basically empty:

{
 “public”: {}
}

Mup.json is where the important stuff happens:

Make sure you specify the latest version of node currently available!

{
  // Server authentication info
  "servers": [
    {
      "host": "meteor",           // You droplet name
      "username": "root",
      "password": "yeahright"
      // or pem file (ssh based authentication)
      //"pem": "~/.ssh/id_rsa"
    }
  ],

  // Install MongoDB in the server, does not destroy local MongoDB on future setup
  "setupMongo": true,

  // WARNING: Node.js is required! Only skip if you already have Node.js installed on server.
  "setupNode": true,

  // WARNING: If nodeVersion omitted will setup 0.10.33 by default. Do not use v, only version number.
  "nodeVersion": "0.10.33",

  // Install PhantomJS in the server
  "setupPhantom": true,

  // Application name (No spaces)
  "appName": "MovieAtMyPlace",

  // Location of app (local directory)
  "app": "/srv/MovieAtMyPlace/",

  // Configure environment
  "env": {
    "ROOT_URL": "http://localhost",
    "PORT": 3001
  },

  // Meteor Up checks if the app comes online just after the deployment
  // before mup checks that, it will wait for no. of seconds configured below
  "deployCheckWaitTime": 15
}

Notice how the ROOT_URL is still localhost and PORT is 3001. Also, if you've got any environment variables (like email api key) then list them under "env".

Now, run apt-get install sshpass, it is a requirement of mup. Then mup setup and mup deploy while you are in the same folder where your mup.json is. Next we can connect your custom port to Nginx.

Nginx — reverse proxy

Nginx should come with the node droplet that DigitalOcean provides. Run the command nginx to see if it is installed.

I’ve got all my configurations in one file. Here’s my /etc/nginx/sites-available/meteor

(notice: this file needs to be symlinked into sites-enabled with ln -s /etc/nginx/sites-available/meteor /etc/nginx/sites-enabled/meteor)

server {
 listen 80;

 server_name movieatmyplace.com;

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

The important bits are server_name and proxy_pass.

After configuring Nginx, run service nginx restart.

Extra

This is not part of the setup, but rather a helper command so you can update the app code from git and deploy in one single command. I myself have a whole menu of these for all kinds of ssh operations.

ssh root@187.22.154.76 "cd /srv/$2/ && git pull && cd /srv/$1_deployment/ && mup deploy";

SSL

Haven't tested this myself, but MUp does have SSL support, learn more here.

Debugging

Occasionally you'll get errors with mup deploy. In the worst case you'll get a very much non-informative error. Here are a few debugging tips.

1. update mup

Update MUp with npm update mup -g. This usually means updating the Node version in your mup.json to the version specified in the example file.

2. check logs

While in the same directory as your mup.json have a look at the logs with the command mup logs -n 600.

3. run local dev

Run the app as a development environment just like you would on your local computer with the command meteor --port=3111 (install Meteor first) and see if it actually runs.

4. enable swap

Deploying multiple apps can take a lot of memory. It doesn't make sense to buy a better server, as most of that memory is automatically freed up when the app is live. So to prevent errors just enable swap space.


How did this setup work out for you?