Skip to content

Instantly share code, notes, and snippets.

@DavidReinberger
Last active December 16, 2020 23:41
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save DavidReinberger/d4517b28320bbd06d2a9 to your computer and use it in GitHub Desktop.
Save DavidReinberger/d4517b28320bbd06d2a9 to your computer and use it in GitHub Desktop.
Running Meteor.js apps on Digital Ocean with Phusion Passenger and NGNIX

How to setup Meteor.js with Phusion Passenger and ngnix

Introduction

This article will guide you thru running a production ready meteor.js app on Digital Ocean with Phusion Passenger and ngnix.

Quick Summary

  1. Create a droplet
  2. Install Phusion Passanger with NGNIX
  3. Install node.js
  4. Configure NGNIX
  5. Run NGNIX on server reboot
  6. Bundle your app a deploy for production
  7. Make it run!
  8. Check for errors

1. Create a droplet

Go to your account and crate a Droplet, choose a plan, deployment infrastructure (US, EU, ASIA) and OS (we will be working with Debian 7 x64 droplet). If you are deploying a production ready app, make sure to run it with at least 1GB RAM.

2. Installing Phusion Passenger with NGNIX

Passenger is very similar to NGNIX or APACHE, it can run as a standalone server or a module to APACHE or NGNIX, we are going to use it with ngnix. Passenger also takes care of starting/restarting out app, which simplifies the setup a lot.

  1. To install anything on your server you have to use ssh. Which is present on any UNIX-like system. If you are on windows please use PUTTY or other ssh client.

ssh root@DROPLET_IP

If this is your first time logging in to the droplet, the system will ask you to change your ssh password.

  1. Install passenger

Follow this tutorial up to the end of step 2.3.3.

The tutorial asks you couple of times to do some file editing, If you are not familiar with UNIX systems use sudo nano /path/ to edit the file. nano is a file editor.

After you are done editing with nano push ctr + x to exit than y to confirm changes and enter to go back to ssh. Or ctrl + o to Write Out change and enter to confirm and ctrl + x to exit.

This will install Passenger along with NGNIX. You can check that everything went fine by visiting YOUR_SERVER_IP and you should see a ngnix welcome screen.

3. Install node.js

Passenger is just a server and it does not take care of installing node.js for you, so we'll have to do it.

  1. Setup system

apt-get install curl

curl -sL https://deb.nodesource.com/setup | bash -

  1. Install node.js

apt-get install -y nodejs

  1. Don't forget to install build essentials!

Build essentials come in handy when you deploy your meteor app afterwards because meteor uses bcrypt which needs to be recompiled on each system.

apt-get install -y build-essential

4. Configure NGNIX

Since we are running NGNIX we'll have to configure it to make use of Passenger.

  1. Open the sites-available/default with nano editor

sudo nano /etc/nginx/sites-available/default

  1. Setup your vhost conf by editing the file

You should see that there is already a server {} block, scroll pass it and copy/paste the following

  server {
    listen 80;

    server_name http://yourserver.domain.com; #same as ROOT_URL
    root /var/www/YOURAPPNAME/public; #DO NOT FORGET THE CHANGE THE NAME

    passenger_enabled on;
    passenger_sticky_sessions on;

    passenger_set_cgi_param MONGO_URL mongodb://username:passowrd@server.com/database; #DO NOT FORGET TO CHANGE IT
    passenger_set_cgi_param MONGO_OPLOG_URL mongodb://username:password@server.com/database?authSource=database; #DO NOT FORGET TO CHANGEIT
    passenger_set_cgi_param ROOT_URL http://yourserver.domain.com;
    passenger_set_cgi_param METEOR_SETTINGS '{}'; #If you are using 'meteor --settings settings.json' in development, copy paste your values here

    passenger_app_type node;
    passenger_startup_file main.js;
  }

This basically tells ngnix to listen for incoming traffic at port 80 which points to your server name and uses passenger module to handle the request. MONGO_URL, MONGO_OPLOG_URL and ROOT_URL are needed by Meteor to run. The last two lines tells passenger that our app is a node app and starts with main.js.

After you are done editing push ctr + x to exit than y to confirm changes and enter to go back to ssh. Or ctrl + o to Write Out change and enter to confirm and ctrl + x to exit.

4. Run ngnix on server reboot

By default ngnix or passenger are not started on server boot, we have to handle that.

  1. Create a file in /etc/init.d/ called ngnix.sh

sudo nano /etc/init.d/ngnix.sh

  1. Paste this line to the file

/etc/init.d/nginx start

After you are done editing push ctr + x to exit than y to confirm changes and enter to go back to ssh. Or ctrl + o to Write Out change and enter to confirm and ctrl + x to exit.

Now whenever the droplet reboots the ngnix server will start.

5. Bundle your app and deploy it to the droplet

Bundling meteor apps is very easy, because meteor CLI give is the great functionality of meteor bundle

  1. Open a new terminal Window
  2. Cd into your Meteor app
  3. Bundle your meteor app

meteor bundle bundle.tar.gz

  1. Upload the bundle to the server

scp bundle.tar.gz root@DROPLET_IP:

login with password

  1. login to your serve again via ssh
  2. Create the /var/www/ directory, cd to it, and extract the bundle

sudo mkdir /var/www/ && cd ../var/www/ #create and change directory

sudo tar xzvf ~/budnle.tar.gz #extracts the bundle to ./bundle

sudo mv bundle YOURAPPNAME #rename the bundle folder to your desired name

  1. Create public and tmp directories which are needed by Passenger

mkdir -p YOURAPPNAME/public YOURAPPNAME/tmp

  1. Install dependencies Meteor bundle turns the meteor app in to almost standard node app so we have the install the dependencies.

cd YOURAPPNAME/programs/server && sudo npm install

  1. Reinstall npm-bcrypt Unfortunately Meteor bundle also, bundles npm-bcrypt which needs to be compiled on every platform, so if you bundled the app on OSX or Windows Machine the app wont start, and will give you bcrypt_lib.node: invalid ELF error. So we need to rebuild bcrypt.

  2. Delete the current npm-directory and recreate it a now

rm -rf npm/npm-bcrypt/ && mkdir -p npm/npm-bcrypt/node_modules/bcrypt/

  1. Move to the projects root directory

cd ../../

  1. Install npm-bcrypt

npm install bcrypt

  1. Now move it to the recreated npm-directory

cp -r node_modules/bcrypt programs/server/npm/npm-bcrypt/node_modules/

6. Make it RUN!

So far it everything went butter smooth you should have a working Meteor deployment on Digital Ocean and Phusion Passenger

  1. Restart ngnix

/etc/init.d/nginx restart

  1. Visit your domain name provider and create an A record which points to your DROPLET_IP
  2. Visit https://cloud.digitalocean.com/domains and configure it accordingly to your DNS and ngnix default configuration
  3. Save all of those settings
  4. It will take 30 min probably to synchronise DNS records
  5. Visit your page!

7. Error checking

App is not running? ngnix does not want to start?

sudo nano /var/log/nginx/error.log

@serkandurusoy
Copy link

In fact, if you don't install nginx, but instead install passenger nginx integration mode directly, you don't need to configure nginx separately for restarts etc. Additionally, I find it easier to deploy as a meteor app instead of a node app, but just run it with the --production flag. This way, you don't have to install node separately, and you don't need to run meteor bundle for every update of your app.

@DavidReinberger
Copy link
Author

@serkadurusoy There is no mentioning that you have to install ngnix separately the second point says Install Phusion Passenger with ngnix, which is almost the same as passenger nginx integration mode. And yes you do have to configure ngnix to start after a droplet reboot. Go on and try to reboot a DO droplet without that init.d script, it just won't startup until you ssh in to your server and start it manually.

@javdl
Copy link

javdl commented Feb 9, 2015

@serkandurusoy This is not recommended in production! Use bundles for that. See also this excellent post: http://projectricochet.com/blog/rolling-your-own-meteor-js-environment#.VNktbYakqK0

@LazerJesus
Copy link

did you forget to explain how to setup mongo?

@LazerJesus
Copy link

and how to run the app in the end?
because i got nginx running when i go to the domain, but it doesnt serve my app...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment