Tutorial

How To Deploy a Meteor.js Application on Ubuntu 14.04 with Nginx

Published on September 22, 2014
How To Deploy a Meteor.js Application on Ubuntu 14.04 with Nginx

About Meteor.js

Meteor.js is a framework for JavaScript that allows web developers to write JavaScript code once and reuse it both client and server-side. This is possible thanks to Meteor’s unique build process (read more about structuring your application code and code sharing). This also solves the problem of needing a complicated deployment process between development mode, where developers code and debug, and production mode, that is secure enough for the public-facing version of the app. The Meteor framework provides a way for client-code and server-code as well as development and production to be closely related. It’s probably the easiest way for client-side developers to start working on server-side code!

To see this in action, you may want to view the introductory video on Meteor’s website.

Meteor.js allows you to develop projects like a website (web application), HTML5-based web-browser application (using AppCache), or mobile application (through integration with PhoneGap). All you need is knowledge of Javascript and HTML. Meteor includes support for MongoDB (a NoSQL database). Atmosphere hosts packages that can provide complete building blocks for your application to speed up the development even more.

At the end of this tutorial, we will have:

  • Installed Meteor.js
  • Created a deployment package that contains an entire Meteor application in a production-ready format (minus a web server and database backend)
  • Installed Nginx as our web server to pass HTTP requests to Meteor
  • Installed MongoDB as our database engine
  • Managed our application with Upstart
  • Configured daily database backups for the Meteor database

Throughout this tutorial, if you don’t have your own Meteor application yet, you can use the “Todo List” example application from the Meteor website.

Before You Begin

You should have:

  • An existing Meteor app on a separate development computer (you can view the example “Todo List” app here; instructions are provided later in the tutorial)

  • A fresh Ubuntu 14.04 server; existing Meteor installations should work in most cases

  • root access to the server to execute commands

  • Updated package lists. Execute:

     apt-get update
    
  • Replace todos.net with the domain name you are actually using (or leave it if you don’t have a domain and will be using an IP address instead)

  • Replace todos (without .net) with the name of your application

Step 1 — Setting Up an Nginx Web Server

We will install and set up Nginx because it allows us to encrypt web traffic with SSL, a feature that Meteor’s built-in web server does not provide. Nginx will also let us serve other websites on the same server, and filter and log traffic.

In our configuration, we will secure our site with an SSL certificate and redirect all traffic from HTTP to HTTPS. We will also utilize a few new security practices to enhance the security of the SSL connection.

In order to install Nginx we execute:

apt-get install nginx

Create a virtual host configuration file in /etc/nginx/sites-available.

Below is an annotated config file which we can create as /etc/nginx/sites-available/todos with the following contents. Explanations for all of the configuration settings are included in the comments in the file:

server_tokens off; # for security-by-obscurity: stop displaying nginx version

# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTP
server {
    listen 80 default_server; # if this is not a default server, remove "default_server"
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html; # root is irrelevant
    index index.html index.htm; # this is also irrelevant

    server_name todos.net; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.

    # redirect non-SSL to SSL
    location / {
        rewrite     ^ https://$server_name$request_uri? permanent;
    }
}

# HTTPS server
server {
    listen 443 ssl spdy; # we enable SPDY here
    server_name todos.net; # this domain must match Common Name (CN) in the SSL certificate

    root html; # irrelevant
    index index.html; # irrelevant

    ssl_certificate /etc/nginx/ssl/todos.pem; # full path to SSL certificate and CA certificate concatenated together
    ssl_certificate_key /etc/nginx/ssl/todos.key; # full path to SSL key

    # performance enhancement for SSL
    ssl_stapling on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    # safety enhancement to SSL: make sure we actually use a safe cipher
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

    # config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
    # to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
    add_header Strict-Transport-Security "max-age=31536000;";

    # If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
    # This works because IE 11 does not present itself as MSIE anymore
    if ($http_user_agent ~ "MSIE" ) {
        return 303 https://browser-update.org/update.html;
    }

    # pass all requests to Meteor
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # allow websockets
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

        # this setting allows the browser to cache the application in a way compatible with Meteor
        # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
        # the root path (/) MUST NOT be cached
        if ($uri != '/') {
            expires 30d;
        }
    }
}

If you’d like to adapt the configuration file to your needs, and for more explanation, have a look at this tutorial on Nginx virtual hosts.

As seen in the virtual host config file, Nginx will expect a valid SSL certificate and key in /etc/nginx/ssl. We need to create this directory and secure it:

mkdir /etc/nginx/ssl
chmod 0700 /etc/nginx/ssl

Then we can create the files containing the certificate (and chain certificate if required) and the key in the locations we defined in the configuration above:

  • certificate: /etc/nginx/ssl/todos.pem
  • key: /etc/nginx/ssl/todos.key

If you do not have an SSL certificate and key already, you should now create a self-signed certificate using this tutorial on creating self-signed SSL certificates for Nginx. Remember that you’ll want to use the same names from the configuration file, like todos.key as the key name, and todos.pem as the certificate name. While a self-signed certificate is fine for testing, it is recommended to use a commercial, signed certificate for production use. A self-signed certificate will provoke Nginx warnings connected to ssl_stapling, and a security warning in the web browser.

When you’re done creating or obtaining your certificate, make sure you have the todos.pem and todos.key files mentioned above.

Next, we should disable the default vhost:

rm /etc/nginx/sites-enabled/default

And enable our Meteor vhost:

ln -s /etc/nginx/sites-available/todos /etc/nginx/sites-enabled/todos

Test that the vhost configuration is error free (you will see an error related to ssl_stapling if you have a self-signed certificate; this is okay):

nginx -t

If everything is looking good we can apply the changes to Nginx:

nginx -s reload

At this point, you can use your web browser to visit https://todos.net (or your IP address). It will show us 502 Bad Gateway. That is OK, because we don’t have Meteor running yet!

Step Two — Setting Up a MongoDB Database

We will install MongoDB from the regular Ubuntu repository. The standard configuration should be fine. There is no authentication required to connect to the database, but connections are only possible from localhost. This means that no external connections are possible, and thus the database is safe, as long as we don’t have untrusted users with SSH access to the system.

Install the MongoDB server package:

apt-get install mongodb-server

This is everything we need to do to get MongoDB running. To be sure that access from external hosts is not possible, we execute the following to be sure that MongoDB is bound to 127.0.0.1. Check with this command:

netstat -ln | grep -E '27017|28017'

Expected output:

tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN
unix  2      [ ACC ]     STREAM     LISTENING     6091441  /tmp/mongodb-27017.sock

In order to have daily backups available in case something goes wrong, we can optionally install a simple command as a daily cron job. Create a file /etc/cron.d/mongodb-backup:

@daily root mkdir -p /var/backups/mongodb; mongodump --db todos --out /var/backups/mongodb/$(date +'\%Y-\%m-\%d')

Step 3 — Installing the Meteor Application

First, we need to install Node.js. Since Meteor typically requires a version of Node.js newer than what’s available in the standard repository, we will use a custom PPA (at the time of writing, Ubuntu 14.04 provides nodejs=0.10.25~dfsg2-2ubuntu1 while Meteor 0.8.3 requires Node.js 0.10.29 or newer).

Execute the following to add a PPA with Node.js, and confirm by pressing Enter:

add-apt-repository ppa:chris-lea/node.js

Output:

 Evented I/O for V8 javascript. Node's goal is to provide an easy way to build scalable network programs
 More info: https://launchpad.net/~chris-lea/+archive/ubuntu/node.js
Press [ENTER] to continue or ctrl-c to cancel adding it

gpg: keyring `/tmp/tmphsbizg3u/secring.gpg' created
gpg: keyring `/tmp/tmphsbizg3u/pubring.gpg' created
gpg: requesting key C7917B12 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmphsbizg3u/trustdb.gpg: trustdb created
gpg: key C7917B12: public key "Launchpad chrislea" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK

Now we must refresh the repository cache, and then we can install Node.js and npm (Node.js package manager):

apt-get update
apt-get install nodejs

It’s a good practice to run our Meteor application as a regular user. Therefore, we will create a new system user specifically for that purpose:

adduser --disabled-login todos

Output:

Adding user `todos' ...
Adding new group `todos' (1001) ...
Adding new user `todos' (1001) with group `todos' ...
Creating home directory `/home/todos' ...
Copying files from `/etc/skel' ...
Changing the user information for todos
Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n]

Step Four — Configuring Upstart

Now we are ready to create the Upstart service to manage our Meteor app. Upstart will automatically start the app on boot and restart Meteor in case it dies. You can read more about creating Upstart service files in this tutorial.

Create the file /etc/init/todos.conf. Once again, it is annotated in-line:

# upstart service file at /etc/init/todos.conf
description "Meteor.js (NodeJS) application"
author "Daniel Speichert <daniel@speichert.pro>"

# When to start the service
start on started mongodb and runlevel [2345]

# When to stop the service
stop on shutdown

# Automatically restart process if crashed
respawn
respawn limit 10 5

# we don't use buil-in log because we use a script below
# console log

# drop root proviliges and switch to mymetorapp user
setuid todos
setgid todos

script
    export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
    # set to home directory of the user Meteor will be running as
    export PWD=/home/todos
    export HOME=/home/todos
    # leave as 127.0.0.1 for security
    export BIND_IP=127.0.0.1
    # the port nginx is proxying requests to
    export PORT=8080
    # this allows Meteor to figure out correct IP address of visitors
    export HTTP_FORWARDED_COUNT=1
    # MongoDB connection string using todos as database name
    export MONGO_URL=mongodb://localhost:27017/todos
    # The domain name as configured previously as server_name in nginx
    export ROOT_URL=https://todos.net
    # optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
    export METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
    # this is optional: http://docs.meteor.com/#email
    # commented out will default to no email being sent
    # you must register with MailGun to have a username and password there
    # export MAIL_URL=smtp://postmaster@mymetorapp.net:password123@smtp.mailgun.org
    # alternatively install "apt-get install default-mta" and uncomment:
    # export MAIL_URL=smtp://localhost
    exec node /home/todos/bundle/main.js >> /home/todos/todos.log
end script

One thing to notice in this configuration file is the METEOR_SETTINGS parameter. If you use meteor --settings config.json when launching Meteor’s development mode, then you should paste the contents of config.json as a variable in METEOR_SETTINGS.

The MAIL_URL must be a valid SMTP URL only if you plan to use Meteor’s Email package. You can use MailGun (as recommended by Meteor), a local mail server, etc.

As we can see in the file, the log will be saved to /home/todos/todos.log. This file will not rotate and WILL GROW over time. It’s a good idea to keep an eye on it. Ideally, there should not be a lot of content (errors) in it. Optionally, you can set up log rotation or replace >> with > at the end of Upstart scripts in order to overwrite the whole file instead of appending to the end of it.

Don’t start this service yet as we don’t have the actual Meteor application files in place yet!

Step Five — Deploying the Meteor Application

Optional: If you do not have a Meteor project yet

If you don’t have a Meteor project yet and would like to use a demo app, that’s not a problem!

Do this next step on your home computer or a development Linux server. Commands may vary based on your OS. Move to your home folder:

cd ~

First, install Meteor’s development version:

curl https://install.meteor.com | /bin/sh

Then create an application from an example, called Todo List:

meteor create --example todos

Now enter the directory of your application and you are ready to continue:

cd todos

All Meteor projects

It’s time to create a production-version bundle from our Meteor app. The following commands should be executed on your home computer or development Linux server, wherever your Meteor application lives. Go to your project directory:

cd /app/dir

And execute:

meteor build .

This will create an archive file like todos.tar.gz in the directory /app/dir. Copy this file to your ~ directory on your Droplet.

scp todos.tar.gz root@todos.net:~

Now go back to your Droplet. Create a project directory and move the archive project file into it. Note that this is the home folder for the project user that we created previously, not your root home folder:

mkdir /home/todos
mv todos.tar.gz /home/todos

Move into the project directory and unpack it:

cd /home/todos
tar -zxf todos.tar.gz

Take a look at the project README:

cat /home/todos/bundle/README

The bundle includes a README file with contents:

This is a Meteor application bundle. It has only one external dependency:
Node.js 0.10.29 or newer. To run the application:

  $ (cd programs/server && npm install)
  $ export MONGO_URL='mongodb://user:password@host:port/databasename'
  $ export ROOT_URL='http://example.com'
  $ export MAIL_URL='smtp://user:password@mailhost:port/'
  $ node main.js

Use the PORT environment variable to set the port where the
application will listen. The default is 80, but that will require
root on most systems.

Find out more about Meteor at meteor.com.

This recipe is reflected in our /etc/init/todos.conf file. There is still one more thing mentioned in the README that we need to do.

Now we need to install some required npm modules. To be able to build some of them, we also need to install g++ and make:

apt-get install g++ make
cd /home/todos/bundle/programs/server
npm install

You should see output like this:

npm WARN package.json meteor-dev-bundle@0.0.0 No description
npm WARN package.json meteor-dev-bundle@0.0.0 No repository field.
npm WARN package.json meteor-dev-bundle@0.0.0 No README data
 
> fibers@1.0.1 install /home/todos/bundle/programs/server/node_modules/fibers
> node ./build.js

`linux-x64-v8-3.14` exists; testing
Binary is fine; exiting
underscore@1.5.2 node_modules/underscore

semver@2.2.1 node_modules/semver

source-map-support@0.2.5 node_modules/source-map-support
└── source-map@0.1.29 (amdefine@0.1.0)

fibers@1.0.1 node_modules/fibers

The reason we need to do this is because our application bundle does not contain modules and libraries that are platform-dependent.

We are almost ready to run the application, but since we operated on files as root, and they should be owned by the todos user, we need to update the ownership of the project directory:

chown todos:todos /home/todos -R

Step Six — Showtime

At this point we have everything we need to run our Meteor application:

  • Node.js environment installed
  • Application installed in its project directory
  • Upstart service configured to run the application
  • MongoDB database
  • Nginx proxy server in front of our Meteor application to provide SSL encryption

To start our application, let’s execute this command from the project directory:

start todos

Now you should be able to view your application in the browser at https://todos.net.

Re-deploying the Application

When you make changes in the development mode (and you will; we are developers after all!), you can simply repeat Step Five (starting from meteor build) and go through most of the steps until the restart todos command, which will reload your application via Upstart.

This way you can push a new version with no downtime. Clients (visitors to your website) will automatically pull the new version of code and refresh their page - that is Meteor’s magic!

If you want to test this, you can make a simple change to the text in the todos/client/todos.html page in your development copy of the app on your home computer or development server.

Development server:

Build:

meteor build /app/dir

Upload:

scp todos.tar.gz root@todos.net:/home/todos

Production server:

Expand:

tar -zxf /home/todos/todos.tar.gz

Move into the project folder:

cd /home/todos/bundle/programs/server

Update the npm modules (you may see a few warnings):

npm install

Restart the app:

restart todos

Troubleshooting

If something goes wrong, here are a few hints on where to look for problems:

  • Check /home/todos/todos.log if your application starts and dies; it should throw an appropriate error message (e.g. in case of a programming error).
  • Check /var/log/nginx/error.log if you see an HTTP error in stead of your application.
  • Check /var/log/mongodb/mongodb.log if you think there might a problem with the database.

Finally, check if all services are running:

status todos
service nginx status
status mongodb

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Daniel Speichert
Daniel Speichert
See author profile
Category:
Tutorial

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
69 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Great article, very helpful.

I always end up with this error though:

/home/****/bundle/programs/server/node_modules/fibers/future.js:173
            throw(ex);
                  ^
Error: /home/****/bundle/programs/server/npm/npm-bcrypt/node_modules/bcrypt/build/Release/bcrypt_lib.node: invalid ELF header
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at bindings (/home/****/bundle/programs/server/npm/npm-bcrypt/node_modules/bcrypt/node_modules/bindings/bindings.js:74:15)
    at Object.<anonymous> (/home/****/bundle/programs/server/npm/npm-bcrypt/node_modules/bcrypt/bcrypt.js:1:97)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

Any ideas?

Never mind - that only seems to happen with the meteor-boilerplate project. Just running a simple meteor app totally works. :)

Thanks again for the guide.

If anyone else has an issue like this with bcrypt - the app probably has its own copy in /home/yourapp/bundle/programs/server/npm/npm-bcrypt/node_modules/bcrypt/

delete that noise. Then do this.

cd /home/yourapp/bundle/programs/server
npm install bcrypt

Then

cp -r /home/yourapp/bundle/programs/server/node_modules/bcrypt /home/yourapp/bundle/programs/server/npm/npm-bcrypt/node_modules/bcrypt/

then start your app and enjoy the meteory goodness.

You are my hero!

I also made a Dockerfile embedding this awesome fix!

https://gist.github.com/giordanocardillo/f7d4a26ebe0bffc4dc25232c7325c1dc

I also got problem with bcrypt. Followed your instruction, but seems like command "cp -r <source> <destination> " is not correct, you should remove “bcrypt/” at the end of <destination> path, then your fix works perfectly. Anyway thank you, saved my Sunday evening.

This fix worked for me also with the tweak from @golojads. Thanks guys.

I tried the above with the tweak and am getting this error in the logs:

/home/todos/bundle/programs/server/node_modules/fibers/future.js:173 throw(ex); ^ Error: Can’t find npm module ‘bcrypt’. Did you forget to call ‘Npm.depends’ in package.js within the ‘npm-bcrypt’ package? at Object.Npm.require (/home/todos/bundle/programs/server/boot.js:117:17) at Package (packages/npm-bcrypt/wrapper.js:1:1) at /home/todos/bundle/programs/server/packages/npm-bcrypt.js:21:4 at /home/todos/bundle/programs/server/packages/npm-bcrypt.js:30:3 at /home/todos/bundle/programs/server/boot.js:175:10 at Array.forEach (native) at Function..each..forEach (/home/todos/bundle/programs/server/node_modules/underscore/underscore.js:79:11) at /home/todos/bundle/programs/server/boot.js:86:5

Any ideas on how to fix greatly appreciated.

This comment has been deleted

    The “cp -r” fix just worked for me. Thanks! :)

    Thanks, it works!

    I’m getting this error

    2014/10/07 23:45:03 [error] 3266#0: *135 connect() failed (111: Connection refused) while connecting to upstream, client: 208.123.162.2, server: mysite.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:8080/favicon.ico", host: "mysite.com"
    

    trying to configure nginx without ssl, here is my config:

    # HTTP
    server {
        listen 80 default_server; # if this is not a default server, remove "default_server"
        listen [::]:80 default_server ipv6only=on;
    
        root /usr/share/nginx/html; # root is irrelevant
        index index.html index.htm; # this is also irrelevant
    
        server_name mysite.com; # the domain on which we want to host the application. Since we set "default_server" previously, nginx will answer all hosts anyway.
    
        # If your application is not compatible with IE <= 10, this will redirect visitors to a page advising a browser update
        # This works because IE 11 does not present itself as MSIE anymore
        if ($http_user_agent ~ "MSIE" ) {
            return 303 https://browser-update.org/update.html;
        }
    
        # pass all requests to Meteor
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade; # allow websockets
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP
    
            # this setting allows the browser to cache the application in a way compatible with Meteor
            # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
            # the root path (/) MUST NOT be cached
            if ($uri != '/') {
                expires 30d;
            }
        }
    }
    

    can you help me figure out this issue?

    This error is expected at that point. Continue to the end of the article and it will start working.

    For people getting this error after completing the tutorial (I did), here are some tips that helped me figure it out.

    • This error seems to be because meteor isn’t starting correctly; probably not an nginx issue.
    • I needed to build for the os.linux.x86_64 architecture (you do too if you’re using a linux droplet), but my dev machine is a mac. In step 5, don’t do meteor build .. Instead, do meteor build --architecture os.linux.x86_64. Like before, you’ll upload the tarball it generates onto your droplet and unpack it in the /home/your-app folder. You will again need to head into /home/todos/bundle/programs/server and then npm install.
    • Figuring out that this was a problem was difficult because we’re starting meteor with upstart – for me it was swallowing error messages and not putting them into the /home/your-app/your-app.log error log (no idea why). You’ll have a much easier time debugging the issues with starting meteor if you try starting it yourself – that way you’ll see errors as they happen and you can troubleshoot them. So, Instead of doing start your-app, go ahead and run the corresponding script that upstart uses to start meteor, found within the script section of /etc/init/your-app.conf. I.e. run these commands directly
    export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
    export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript 
    export PWD=/home/your-app 
    export HOME=/home/your-app 
    export BIND_IP=127.0.0.1 
    export PORT=8080 
    export HTTP_FORWARDED_COUNT=1 
    export MONGO_URL=mongodb://localhost:27017/your-app 
    export ROOT_URL=https://shpow.ca 
    exec node /home/your-app/bundle/main.js 
    
    • Once meteor starts properly, you can go back to using upstart.

    HTH

    I have finished all the other steps, everything seems to be running, but i get a 502 Bad Gateway, with the error from my previous post in the log

    Check the logs mentioned in “Troubleshooting” as well as /var/log/upstart/todos.log

    /home/todos/todos.log is empty and all services are running, any thoughts?

    Btw, I did not do this step “add-apt-repository ppa:chris-lea/node.js”, the nodeJS version seems be the latest on the droplet already

    hmm looks like the same issue as will751517 mentioned, let me try to fix, thanks for the help

    I also have that problem… How do I solve it?

    I was having the same problem… after 4 hours it is now working!

    Here is what I did: A- make sure when you delete the “SSH” part, that the remaining “location” is enclosed inside the “Server” bracket… this typo took me a while to notice!

    B- if that doesn’t solve it:

    1 - check /var/log/upstart, look for <your-app-name>.log 2- in my case, the error matched what will751517 described above 3- I deleted the entire “bcrypt” folder from the “npm” folder 4- I did the “npm install bcrypt command” 5- Did NOT do anything else (did not copy to npm folder)

    Hope it works for you!

    This comment has been deleted

      I was having this same problem and @stenio123’s solution solved it for me, thanks so much!

      what is failing you is nginx itself. you deleted the part that sets a value for $connection_upgrade, so nginx cant fill in the parameter. Hope it helps anyone with that error.

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      if you guys were working on mac osx it might be that bcrypt “broke”.

      remove bcrypt folder in todos/bundle/programs/server/npm and todos/bundle/programs/server/node_modules

      reinstal npm install bcrypt

      restart service

      Hope it helps. :)

      http://stackoverflow.com/a/20590261/1504455

      MUP (Meteor Up) can replace step 4 and when you need to redeploy just run mup deploy instead of step 5.

      https://github.com/arunoda/meteor-up

      Actually if you are going to use MUP you might want to look at this article http://code.krister.ee/hosting-multiple-instances-of-meteor-on-digitalocean/ because although this digitalocean article is very detailed it is also much more complicated than a deployment using MUP would be.

      Thanks for posting this. I was wondering if mup could simplify a few of the steps here.

      Now Meteor UP has the SSL support. Check this guide. it’s pretty simple and just a two lines of configuration.

      I am receiving this repeated error:

      Error: listen EADDRINUSE at errnoException (net.js:904:11) at Server._listen2 (net.js:1042:14) at listen (net.js:1064:10) at net.js:1146:9 at dns.js:72:18 at process._tickCallback (node.js:419:13)

      I think the problem is with the nginx configuration. Any ideas?

      Kamal Nasser
      DigitalOcean Employee
      DigitalOcean Employee badge
      November 2, 2014

      That means that there is already a process listening on port 8080 so Meteor.js isn’t able to bind to it. You can find out what that process is by running:

      sudo netstat -plutn | grep 8080
      

      I was using the same port in another app. Fixed.

      Thanks,

      Why it s complex?) I will recommend you to create for example chief or puppet recipes for every tutorial)) I am tired after doing these all steps.

      Hi, no matter what, I get a 502 bad gateway error. I think it’s because of step 5:

      Now go back to your Droplet. Create a project directory and move the archive project file into it. Note that this is the home folder for the project user that we created previously, not your root home folder:

      All of your steps at this point like mkdir /home/projectname force the creation of the folder in the root’s home folder (because of the slash in front of it), so how are we supposed to use the project user’s home folder?

      Thanks, -Gabe

      Kamal Nasser
      DigitalOcean Employee
      DigitalOcean Employee badge
      November 16, 2014

      Hi!

      It’s the other way, actually :) If the path begins with a slash, it means that it’s an absolute path, so /home/projectname points to /home/projectname, not /root/home/projectname.

      Try starting the service:

      sudo start todos
      

      If that fails, check the log file for errors:

      less /home/todos/todos.log
      

      Hi Kamaln,

      Thanks, but that still didn’t work. The log file says everything has started, and the status says start/running (some random number).

      My only other solution that successfully works in this regard is cloning the (unbundled) files from a Github repository, and then in the app directory running meteor --port 8080 inside of a tmux session.

      How could it be that this works but your method doesn’t?

      Kamal Nasser
      DigitalOcean Employee
      DigitalOcean Employee badge
      November 16, 2014

      Can you please post the output of the following command?

      tail -120 /home/todos/todos.log
      

      Hmm,

      Whereas before if I ran cat todos.log it showed a bunch of ’ ~ ''s and that the process started, it now shows nothing. The terminal goes right to the next command line. Conversely, if I run start todos again, the output is now:

      start: Job is already running: croud
      

      (croud is the name of my app/user)

      ggaabe, I was able to get it working by cutting:

       listen 80 default_server; # if this is not a default server, remove "default_server"
       listen [::]:80 default_server ipv6only=on;
      

      down to simply:

       listen 80;
      

      in the “/etc/nginx/sites-enabled/todos” file.

      I don’t know what I’m sacrificing as a result of doing that, though. I don’t know if your error was the same as mine. Let me know if that does anything for you.

      Hi,

      Thanks. Unfortunately, it still didn’t work :-(

      Hi again,

      So I managed to get ahold of the error logs. (Tried deploying with mup):

      error: Forever detected script exited with code: 8
      [my server IP address] error: Script restart attempt #32
      [my server IP address]
      [my server IP address] events.js:72
      throw er; // Unhandled 'error' event
      [my server IP address] [my server IP address] ^
      Error: listen EADDRINUSE
      at errnoException (net.js:904:11)
      at Server.listen2 (net.js:1042:14)
      at listen (net.js:1064:10)
      at net.js:1146:9
      at dns.js:72:18
      at process.tickCallback (node.js:419:13)
      error: Forever detected script exited with code: 8
      [my server IP address] error: Script restart attempt #33[my server IP address] 
      

      @ggaabe hey, getting the same error. how did you fix this?

      Same here. And the error.log file says something like:

      [error] 4546#0: *17 connect() failed (111: Connection refused) while connecting to upstream

      I really hope we can get this figured out soon, but it’s the same error listed by ran818145 on Oct. 8, and still no solution, posted here at least.

      Kamal Nasser
      DigitalOcean Employee
      DigitalOcean Employee badge
      November 16, 2014

      A connection refused error means that your meteor.js app is not running. Do you get any errors when you start to start the todos service?

      start todos
      

      If that doesn’t work, check the error log for errors:

      less /home/todos/todos.log
      

      There were no errors in my version of “home/todos/todos.log”.

      However, I was able to get it working by cutting:

      listen 80 default_server; # if this is not a default server, remove "default_server"
      listen [::]:80 default_server ipv6only=on;
      

      down to simply:

      listen 80;
      

      in the “/etc/nginx/sites-enabled/todos” file. I don’t know what I’m sacrificing as a result of doing that, though.

      This comment has been deleted

        Interestingly, I get the following error after adding a json string to my METEOR_SETTINGS environment variable. I’ve not been able to find a solution to this yet. I’m on DO, using a Ubuntu 14 droplet. Works fine locally, and worked fine on the server until I added this:

        root@dev:/home/qdev# echo $METEOR_SETTINGS { “public”: { }, “firstUser”: { “id”: “oPMfpAuwQ3nuTdpTA” } } root@dev:/home/qdev#

        Here’s the error:

        module.js:340 throw err; ^ Error: Cannot find module ‘underscore’ at Function.Module._resolveFilename (module.js:338:15) at Function.Module._load (module.js:280:25) at Module.require (module.js:364:17) at require (module.js:380:17) at Object.<anonymous> (/home/qdev/bundle/programs/server/boot.js:5:9) at Module._compile (module.js:456:26) at Object.Module._extensions…js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.require (module.js:364:17)

        Hopefully this helps someone else… I figured out that I had to go into the upstart configuration file (i.e. /etc/init/<appname>.conf and add the:

        export METEOR_SETTINGS=“$(cat /path/to/settings.json)”

        Now everything works swimmingly.

        Thanks!

        I’m running into the same problem as a couple folks above have. I’m getting this:

        2014/11/23 20:33:31 [error] 2949#0: *16 connect() failed (111: Connection refused) while connecting to upstream, client: 174.29.13.110, server: practicalhomesteading.com, request: “GET / HTTP/1.1”, upstream: “http://127.0.0.1:8080/”, host: “practicalhomesteading.com

        in /var/log/nginx/error.log

        I’ve also tried this change:

        listen 80;
        # listen 80 default_server; # if this is not a default server, remove "default_server"
        # listen [::]:80 default_server ipv6only=on;
        

        With no success.

        netstat -plutn | grep 8080

        Returns nothing.

        status todos returns:

        todos start/running, process 10232

        Any suggestions on this?

        I’m fairly confident I’ve followed these instructions correctly. And it seems that

        start todos

        Actually starts the app. Trying to start while running indicates it’s already running.

        But this:

        netstat -plutn

        Doesn’t show anything running on port 8080.

        Kamal Nasser
        DigitalOcean Employee
        DigitalOcean Employee badge
        December 3, 2014

        This comment has been deleted

          By the way, the “Meteor website” link about the example “todo” tutorial is now broken.

          Hello.

          I’m getting “502 Bad Gateway” error.

          “Todos”, nginx and MongoDB is running.

          I have this error in log upstart:

          Exception in callback of async function: Error: failed to connect to [localhost:27017]
              at null.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/server.js:536:74)
              at emit (events.js:106:17)
              at null.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:150:15)
              at emit (events.js:98:17)
              at Socket.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/connection.js:516:10)
              at Socket.emit (events.js:95:17)
              at net.js:440:14
              at process._tickCallback (node.js:419:13)
          

          MeteorApp don’t connect to MongoDB ?

          netstat -ln | grep -E '27017|28017'
          tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN     
          tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN     
          unix  2      [ ACC ]     STREAM     LISTENING     9522     /tmp/mongodb-27017.sock
          

          But MongoDB is working and database for application exist.

          Help me, please.

          Thank you for the great introduction! I managed to setup my meteor server successfully thanks to this article.

          One weird thing is that my app dies silently for some reason. The app dies after several hours after it started. The lasting time is irregular. It doesn’t make any log. I made it log on pre-stop, but it didn’t log as well. Do you have any idea about this?

          After update Meteor to 1.0.2,the website error with 502 Bad Gateway *27730 connect() failed (111: Connection refused) while connecting to upstream, client: 106.186.125.232, server: sharey.birdgg.me, request: “GET / HTTP/1.1”, upstream: “http://127.0.0.1:8080/

          Kamal Nasser
          DigitalOcean Employee
          DigitalOcean Employee badge
          December 25, 2014

          A 502 error means that the meteorjs app isn’t running. Try starting the service:

          sudo start todos
          

          If that fails, check the log file for errors:

          less /home/todos/todos.log
          

          Hi, I’ve been following the topic’s thread. Whenever I type sudo start todos i get the following: start: Unknown job: cuttocontenttemp

          Any idea what could be wrong? Also trying to access the log doesn’t return anything either.

          Kamal Nasser
          DigitalOcean Employee
          DigitalOcean Employee badge
          January 29, 2015

          Hi @ines, does /etc/init/cuttocontenttemp.conf exist? The service should be the same as the init file’s name.

          Hi, fixed some file issues.

          Now when I state start todos I get “cuttocontenttemp start/running, process 8179” but can’t see anything in the browser.

          Is it possible to deploy the meteor app in a sub folder rather than a sub domain. So MyDomain.com/myMeteorApp1. thanks paul.

          I have a question about the ‘start’ command:

          When I use it it seems to be starting the old meteor instance from another domain directory (I redeployed todos), so I’m trying to debug.

          I’ve been able to find out that start todos starts the process through init(8), but the ‘todos’ argument being passed to the start command must be some kind of file or symbolic link, no? I want to be able to ‘nano’-it up to see where’s the target file(s) that start todos is running. Is there a way to do that? Thanks in advance. -Nico

          UPDATE: after digging a little more I found out that the start command corresponds to upstart and that the argument after ‘start’ is the name of the a .conf file in the /etc/init/ folder, which we created earlier in the tutorial as todos.conf. Now I can continue my debugging :)

          SOLVED: the root of the problem was spelled out in the upstart log files. To access the upstart logs navigate to cd /var/log/upstart and you should find there one or many files that starts with todos.log. Once the log gets to certain size upstart automatically compresses the file so you might have to decompress it to see what’s in it. In my case for instance the filename was todos.log.1.gz.

          Once I was able to access the log I saw that I was missing some npm packages that I needed to re-install and also needed to do the bcrypt hack mentioned by @will751517 and @golojads earlier here (you guys were lifesavers).

          So apparently as of Meteor 1.0 if you are building from OS to deploy in Linux, you will probably get the bcrypt error. This is described here

          https://github.com/meteor/meteor/issues/3517

          The solution is use the parameter “–architecture” when running build. Therefore:

          meteor build --architecture os.linux.x86_64

          Good catch. I hope @DSpeichert can update this tutorial to mention the potential need of the --architecture flag. It would’ve save me loads of time.

          This comment has been deleted

            I am sorry, forgot to type the folder. Following the tutorial, it should be

            meteor build /app/dir --architecture os.linux.x86_64
            

            Hi,

            when I tried opening /var/log/nginx/error.log I get “Permission denied” and in my /var/log/upstart/todos.log i have the following errors:

            module.js:340 throw err; ^ Error: Cannot find module ‘/home/ctcadmin/bundle/main.js’ at Function.Module.resolveFilename (module.js:338:15) at Function.Module.load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3

            module.js:340 throw err; ^ Error: Cannot find module ‘/home/ctcadmin/bundle/main.js’ at Function.Module.resolveFilename (module.js:338:15) at Function.Module.load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16)

            Any troubleshooting ideas would be very much appreciated!

            Hello,

            Not sure why it’s saying permission denied as the access permissions state that any user can read the file (-rw-r–r-- 1 root root 8312 Feb 2 17:30 error.log) Just sudo and you can view it, anyway.

            Mine wasn’t working originally but then I rebuilt the project with the ‘architecture’ parameter, too:

            meteor build --server=https://example.com:443 --architecture=os.linux.x86_32

            Note: Your architecture may be different. e.g. 64 bit.

            Hope that helps.

            PORT=3000 ROOT_URL=http://site.com MONGO_URL=mongodb://localhost:27017/chat node start /home/chat/meteor/chat/bundle/main.js

            module.js:340 throw err; ^ Error: Cannot find module ‘/home/chat/meteor/chat/bundle/start’ at Function.Module._resolveFilename (module.js:338:15) at Function.Module._load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3

            cant resolve it( help

            I’m fairly confident I’ve followed these instructions correctly. And it seems that

            start todos

            Actually starts the app. Trying to start while running indicates it’s already running.

            But this:

            netstat -plutn

            Doesn’t show anything running on port 8080.

            Kamal Nasser
            DigitalOcean Employee
            DigitalOcean Employee badge
            December 3, 2014

            This comment has been deleted

              By the way, the “Meteor website” link about the example “todo” tutorial is now broken.

              Hello.

              I’m getting “502 Bad Gateway” error.

              “Todos”, nginx and MongoDB is running.

              I have this error in log upstart:

              Exception in callback of async function: Error: failed to connect to [localhost:27017]
                  at null.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/server.js:536:74)
                  at emit (events.js:106:17)
                  at null.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:150:15)
                  at emit (events.js:98:17)
                  at Socket.<anonymous> (/home/zenresult/bundle/programs/server/npm/mongo/node_modules/mongodb/lib/mongodb/connection/connection.js:516:10)
                  at Socket.emit (events.js:95:17)
                  at net.js:440:14
                  at process._tickCallback (node.js:419:13)
              

              MeteorApp don’t connect to MongoDB ?

              netstat -ln | grep -E '27017|28017'
              tcp        0      0 127.0.0.1:28017         0.0.0.0:*               LISTEN     
              tcp        0      0 127.0.0.1:27017         0.0.0.0:*               LISTEN     
              unix  2      [ ACC ]     STREAM     LISTENING     9522     /tmp/mongodb-27017.sock
              

              But MongoDB is working and database for application exist.

              Help me, please.

              Thank you for the great introduction! I managed to setup my meteor server successfully thanks to this article.

              One weird thing is that my app dies silently for some reason. The app dies after several hours after it started. The lasting time is irregular. It doesn’t make any log. I made it log on pre-stop, but it didn’t log as well. Do you have any idea about this?

              After update Meteor to 1.0.2,the website error with 502 Bad Gateway *27730 connect() failed (111: Connection refused) while connecting to upstream, client: 106.186.125.232, server: sharey.birdgg.me, request: “GET / HTTP/1.1”, upstream: “http://127.0.0.1:8080/

              Kamal Nasser
              DigitalOcean Employee
              DigitalOcean Employee badge
              December 25, 2014

              A 502 error means that the meteorjs app isn’t running. Try starting the service:

              sudo start todos
              

              If that fails, check the log file for errors:

              less /home/todos/todos.log
              

              Hi, I’ve been following the topic’s thread. Whenever I type sudo start todos i get the following: start: Unknown job: cuttocontenttemp

              Any idea what could be wrong? Also trying to access the log doesn’t return anything either.

              Kamal Nasser
              DigitalOcean Employee
              DigitalOcean Employee badge
              January 29, 2015

              Hi @ines, does /etc/init/cuttocontenttemp.conf exist? The service should be the same as the init file’s name.

              Hi, fixed some file issues.

              Now when I state start todos I get “cuttocontenttemp start/running, process 8179” but can’t see anything in the browser.

              Is it possible to deploy the meteor app in a sub folder rather than a sub domain. So MyDomain.com/myMeteorApp1. thanks paul.

              I have a question about the ‘start’ command:

              When I use it it seems to be starting the old meteor instance from another domain directory (I redeployed todos), so I’m trying to debug.

              I’ve been able to find out that start todos starts the process through init(8), but the ‘todos’ argument being passed to the start command must be some kind of file or symbolic link, no? I want to be able to ‘nano’-it up to see where’s the target file(s) that start todos is running. Is there a way to do that? Thanks in advance. -Nico

              UPDATE: after digging a little more I found out that the start command corresponds to upstart and that the argument after ‘start’ is the name of the a .conf file in the /etc/init/ folder, which we created earlier in the tutorial as todos.conf. Now I can continue my debugging :)

              SOLVED: the root of the problem was spelled out in the upstart log files. To access the upstart logs navigate to cd /var/log/upstart and you should find there one or many files that starts with todos.log. Once the log gets to certain size upstart automatically compresses the file so you might have to decompress it to see what’s in it. In my case for instance the filename was todos.log.1.gz.

              Once I was able to access the log I saw that I was missing some npm packages that I needed to re-install and also needed to do the bcrypt hack mentioned by @will751517 and @golojads earlier here (you guys were lifesavers).

              So apparently as of Meteor 1.0 if you are building from OS to deploy in Linux, you will probably get the bcrypt error. This is described here

              https://github.com/meteor/meteor/issues/3517

              The solution is use the parameter “–architecture” when running build. Therefore:

              meteor build --architecture os.linux.x86_64

              Good catch. I hope @DSpeichert can update this tutorial to mention the potential need of the --architecture flag. It would’ve save me loads of time.

              This comment has been deleted

                I am sorry, forgot to type the folder. Following the tutorial, it should be

                meteor build /app/dir --architecture os.linux.x86_64
                

                Hi,

                when I tried opening /var/log/nginx/error.log I get “Permission denied” and in my /var/log/upstart/todos.log i have the following errors:

                module.js:340 throw err; ^ Error: Cannot find module ‘/home/ctcadmin/bundle/main.js’ at Function.Module.resolveFilename (module.js:338:15) at Function.Module.load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3

                module.js:340 throw err; ^ Error: Cannot find module ‘/home/ctcadmin/bundle/main.js’ at Function.Module.resolveFilename (module.js:338:15) at Function.Module.load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16)

                Any troubleshooting ideas would be very much appreciated!

                Hello,

                Not sure why it’s saying permission denied as the access permissions state that any user can read the file (-rw-r–r-- 1 root root 8312 Feb 2 17:30 error.log) Just sudo and you can view it, anyway.

                Mine wasn’t working originally but then I rebuilt the project with the ‘architecture’ parameter, too:

                meteor build --server=https://example.com:443 --architecture=os.linux.x86_32

                Note: Your architecture may be different. e.g. 64 bit.

                Hope that helps.

                PORT=3000 ROOT_URL=http://site.com MONGO_URL=mongodb://localhost:27017/chat node start /home/chat/meteor/chat/bundle/main.js

                module.js:340 throw err; ^ Error: Cannot find module ‘/home/chat/meteor/chat/bundle/start’ at Function.Module._resolveFilename (module.js:338:15) at Function.Module._load (module.js:280:25) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3

                cant resolve it( help

                Hi,

                is it a problem if I don’t see the following under the 3 first lines? :

                npm WARN package.json meteor-dev-bundle@0.0.0 No description npm WARN package.json meteor-dev-bundle@0.0.0 No repository field. npm WARN package.json meteor-dev-bundle@0.0.0 No README data

                **> fibers@1.0.1 install /home/todos/bundle/programs/server/node_modules/fibers

                node ./build.js

                linux-x64-v8-3.14 exists; testing Binary is fine; exiting underscore@1.5.2 node_modules/underscore

                semver@2.2.1 node_modules/semver

                source-map-support@0.2.5 node_modules/source-map-support └── source-map@0.1.29 (amdefine@0.1.0)

                fibers@1.0.1 node_modules/fibers **

                Kamal Nasser
                DigitalOcean Employee
                DigitalOcean Employee badge
                February 2, 2015

                No. As long as you don’t get any errors, you should be fine.

                Could someone please confirm this for me.

                Each time I make any update to my project, I need to rebuild it, upload the tarball, extract the tarball, npm install the app, fix up the bcrypt bug, then restart the process?

                stenio123 has pointed out that the bcrypt bug should be bypassed by building with that architecture flag. thats good. still, updating a project seems quite intense.

                I’ve done some more research into it. MUP confused me more than anything - but after watching this tutorial from Sacha it makes a lot more sense:

                https://www.youtube.com/watch?v=WLGdXtZMmiI

                I am going to try again from scratch using MUP.

                Hi @cstratford

                I wasn’t satisfied with MUP, thinking that it would again a package…

                So I’ve made a script, in case you want to try it: https://github.com/grabcode/db-tools/blob/master/meteor-deploy.sh

                About bcrypt, if it is like me, you simply need to build adding the param --architecture os.linux.x86_64

                I guess we are both on OSX…

                Cheers, Alex

                Hi @grabcode - thanks for jumping in and adding to the conversation!

                Yes I am on OSX.

                After playing around with MUP I am pretty happy with it, it seems to do everything I need and works pretty seamlessly. I will checkout your script as well, anything to make life simpler is a bonus!

                Thanks DO, yet another great tutorial.

                Below the meteor-deploy.sh script to automate the deployment of your Meteor App.

                https://github.com/grabcode/db-tools/blob/master/meteor-deploy.sh

                I’ve wanted to contribute sharing this script. Assuming you went through this tutorial, this script should work. Feel free to contribute - and follow me twitter @grabthecode

                Thanks for the guide! I have one problem though. I get this error in my log file:

                Error: /home/projectfolder/bundle/programs/server/node_modules/fibers/bin/linux-ia32-v8-3.28/fibers.node is missing. Try reinstalling node-fibers?

                I built it with node v0.10.33. I have tried to reinstall fibers but it doesn’t work. I get this when installing fibers:

                npm WARN package.json meteor-dev-bundle@0.0.0 No description npm WARN package.json meteor-dev-bundle@0.0.0 No repository field. npm WARN package.json meteor-dev-bundle@0.0.0 No README data

                fibers@1.0.1 install /home/projectfolder/bundle/programs/server/node_modules/fibers node ./build.js

                linux-ia32-v8-3.14 exists; testing Binary is fine; exiting fibers@1.0.1 node_modules/fibers

                How will i get it to install linux-ia32-v8-3.28?

                Thanks a lot for this tutorial!

                This comment has been deleted

                  Im getting a 404 Error when I hit my domain via https://domain.com (I have to add an exception to my browser to even see the 404 error), and Im not sure what Ive done wrong.

                  My nginx error logs make reference to:

                  “”/usr/share/nginx/www/index.html" is not found (2: No such file or directory)"

                  but I haven’t read that an index.html file is necessary either in this tutorial, or in Meteor docs.

                  What should I do?

                  I’m wondering if anyone else has had any trouble setting the MAIL_URL environment variable in the Upstart script?

                  I’ve followed these instructions and finally started setting (and exporting) the MAIL_URL (as well as some other environment variables. But these never seem to get set for the app.

                  These should be available (inside the Meteor app) here: process.env.<some variable name> like process.env.MAIL_URL.

                  And it appears that everything up to the METEOR_SETTINGS variable gets set, but nothing else.

                  Has anyone else seen this?

                  Further testing reveals that the file /etc/init/<app_name>.conf either is not getting loaded (though some of the variables it sets are set) or it’s not getting re-loaded or re-run after it is changed.

                  Appears that you need to reboot for changes to /etc/init/<app_name>.conf to be picked up.

                  This is working… mostly. I am exporting my METEOR_SETTINGS like this:

                  export METEOR_SETTINGS=$(/bin/cat /home/todos/settings.json)
                  

                  I am getting this error in my /var/log/upstart/todos.log

                  /proc/self/fd/9: 22: export: "bitly": bad variable name
                  

                  Here is the settings.json file:

                  {
                    "bitly" : {
                      "appId" : "my_bitly_app_id",
                      "appSecret" : "my_bitly_app_secret"
                    }
                  }
                  

                  Any help?

                  UPDATE::

                  I used Meteor-Up and it worked perfectly! Please check this out: https://github.com/arunoda/meteor-up#server-configuration

                  Thanks Daniel and Arunoda!

                  Will this work with meteor up? Thanks

                  Thanks for this resource. I created my key & pem files and put them in the right place, and used your site config file, then restarted Nginx, but it’s still refusing https connections. Anyone else have this problem?

                  Kamal Nasser
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  April 9, 2015

                  Run the following command to see if nginx is listening on port 443:

                  sudo netstat -plutn | grep 443
                  

                  If it is, and you still can’t access your site via HTTPS, check if there is a firewall rule that could be blocking connections to port 443:

                  sudo iptables -L -n -v
                  

                  I’m having a similar problem. The site redirect to https and shows up as: This webpage is not available ERR_CONNECTION_TIMED_OUT Sometimes the error is about a redirect problem.

                  I am not getting the ssl_stapling error like I did before when I execute nginx -t

                  When I test my domain name on https://www.sslchecker.com/sslchecker It says “No certificates were found.”

                  Any ideas?

                  Thanks for this great guide! One question though: nginx isn’t serving any css or js (getting MIME type erros in the browser console) and I’ve been trying to solve this by fixing the nginx configuration files without any luck so far. Has anyone had this issue with this config? Any suggestions would be much appreciated!

                  Did anyone get this kind of error on the /var/log/upstart/myApp.logs? If so, how did you resolve it?

                      at Object.Future.wait (/home/bundle/programs/server/node_modules/fibers/future.js:398:15)```

                  In case, anyone else had the same MongoDB error: "In order to execute the command {{listIndexes}}, according to [MongoDB docs|http://docs.mongodb.org/manual/reference/built-in-roles/#read], you need to have the {{read}} role for that database. You will need to grant the role to the appropriate user. " – MMSSUPPORT

                  I could not make the certificate work. Followed the other tutorial, but instead of writing it as described there: sudo openssl req -new -key server.key -out server.csr

                  …I did like this: sudo openssl req -new -key appname.key -out appname.pem and after signing in my certificate, set up it and activate my virtual host, if I type ngynx -t, I get this:

                  nginx: [emerg] PEM_read_bio_X509_AUX("/etc/nginx/ssl/appname.pem") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: TRUSTED CERTIFICATE)
                  nginx: configuration file /etc/nginx/nginx.conf test failed
                  

                  What am I doing wrong? I have double-check to see if my /etc/nginx/sites-available/appname was good, and it does.

                  I think the .pem file is a concatenation of the .crt and .key files. I found this on stackoverflow:

                  // If this is for a Web server, and you cannot specify loading a separate private and public key, you may need to concatenate the two files. For this use: cat server.crt server.key > server.includesprivatekey.pem //

                  According to nginx.org, both ssl_certificate and ssl_certificate_key must be PEM format, so it’s definitely confusing.

                  server.csr is the file you send to the Certificate Authority. The server.key you keep private. You will get a verification email from the CA with instructions (or check their support website) to concatenate the files to create your .pem file. It is complicated so it’s best to follow the instructions exactly. Make sure it works first then modify it later.

                  https://www.digitalocean.com/community/tutorials/how-to-install-an-ssl-certificate-from-a-commercial-certificate-authority

                  Yeah this exact problem/error message was driving me nuts - I spent hours trying different things until I worked out that I was copying the certificates from gmail and it was corrrupting something. There’s an option in gmail to view the message as plain text - it’s called something like “message garbled?” . I clicked it and copied the certificate values from there (both mine and the CA) into the one file and the problem went away.

                  Running:

                  meteor build .

                  in my app directory ( ~/todos) on my development Droplet doesn’t create

                  todos.tar.gz

                  • although it displays progress msgs: “reading package metadata” and “selecting package versions”. Running as root does the same thing. Any ideas?

                  Hmm… meteor bundle todos.tgz works.

                  What’s the difference between bundle and build?

                  Thanks for the awesome tutorial. I think I had to deviate in a couple of places but specifically I had to use meteor build in such a way that the meteor app was listening on port 443:

                  meteor build . --server http://127.0.0.1:443 --architecture os.linux.x86_64
                  

                  You can see above I also used the architecture option per other comments on this page but I’m not sure if I needed it or not. Thanks again.

                  Thanks for this.

                  This works. The article is outdated with the recent version of Meteor.

                  The meteor build . is no longer a valid command. the meteor build -- requires additional arguments.

                  Without additional arguments, you get “hints” as to what is wrong; basically saying the command is invalid without proper arguments.

                  With just meteor build . , nothing happens.

                  meteor bundle
                  

                  …Appears to create a non-OS specific tar.gz of that project. Not sure if this is the new “alternative” to meteor build .

                  Scratch that. Still getting a 502. It appears this tutorial is completely wrong.

                  It gets me so far as to get the index page to load. The rest is crap.

                  @methodbox Not sure what problem you’re having with meteor build, but meteor bundle has been deprecated. You were correct in using meteor build. See https://github.com/meteor/meteor/blob/692f935240ce8d63607c327802ec7f4daa9e311c/History.md#v092-2014-sep-15

                  For anyone using a current Ubuntu 14.04 with Nodejs and having package conflicts, issues installing through NPM or conflicts running npm install you’ll likely need to purge “node” (NOT the same as nodejs) and nodejs, create a symlink to nodejs for your $PATH and then reinstall NodeJS.

                  There is a critical piece of info left out of this article which I’d forgotten as it’s been a while since I played with Ubuntu:

                  Ubuntu includes a module called node which has nothing to do with nodejs.

                  Many modules installed using npm expect nodejs to be in the same $PATH location as Ubuntu’s node module, and as such break on install, and break package.json installs and anything (like Meteor) that relies on them.

                  The fix is below:

                  Remove both “nodes”: sudo apt-get --purge remove node sudo apt-get --purge remove nodejs

                  Create the proper symlink for nodejs: sudo ln -s /usr/bin/nodejs /usr/bin/node

                  Reinstall nodejs: sudo apt-get install nodejs

                  There’s probably an Ubuntu-specific guide somewhere for this but John Papa’s OSX guide for removing the need for sudo with npm is highly recommended if you’re doing a lot of cloud dev for Nodejs. This will make your life a lot easier:

                  http://www.johnpapa.net/how-to-use-npm-global-without-sudo-on-osx/

                  (Also works on Yosemite 10.x)

                  Does this installation of MongoDB have oplog enabled by default?

                  Does anyone ever get stuck on step 1? I followed it & replaced todos with sumbermakmur. Whenever I put my IP or sumbermakmur.net, it would show DNS_PROBE_FINISHED_NXDOMAIN error on Chrome instead of the expected 502 error.

                  I also tried to put a sumbermakmur.net DNS record for my Droplet on cloud.digitalocean.com/domains but that doesn’t seem to help. (if this is relevant, do I have to add & wait for hours?)

                  /var/log/nginx/error.log only shows ssl_stapling warning.

                  Whenever I do wget [my Droplet IP], the access log file (/var/log/nginx/access.log) would show that the request came in & redirected (301) to sumbermakmur.net (which returns DNS_PROBE_FINISHED_NXDOMAIN).

                  Any ping or wget to sumbermakmur.net would return: ping: cannot resolve sumbermakmur.net: Unknown host wget: unable to resolve host address 'sumbermakmur.net'

                  Thank you for the tutorial ! Helped me a lot :)

                  Hi there. No matter what I do, websockets don’t work.

                  Please, if someone happens to come through here, take a look at http://stackoverflow.com/questions/32309595/meteor-nginx-error-during-websocket-handshake-connection-header-value-must

                  Hello i have Meteor.js running ok in Nginx. But I have a problem when I want to use caching. Then I get empty page. What am i doing wrong.

                  Hi, Thanks for this great tutorial, but I juste have a little issue : my service seems to not stay as working . I can start it, but if I check his status, it say “stop/waiting”.

                  I don’t know if it is normal and I’ don’t know where to check to fix the issue. If anybody would have an idea, I would love to hear it :-).

                  Thanks in advance

                  I recommend doing :

                  node /home/productyeah/bundle/main.js >> /home/productyeah/productyeah.log 2>&1

                  in order to also catch any errors, which in my case were:

                  Error: bcrypt/node_modules/bcrypt/build/Release/bcrypt_lib.node: invalid ELF header

                  hello i get 502 error and i checked the /var/log/upstart/todos.log file and i get this message Meteor requires Node v0.10.40 or later. i already reinstall node meteor nginx but i still get this message at todos.log

                  Awesome stuff. I’m having an issue when trying to incorporate mailgun with my app. I set the MAIL_URL in the startup function on the server and it seems to work perfectly when I run it on my local machine. As soon as I deploy it to the server(from this tutorial), it looks like the email request gets hung up. I was wondering if any of the settings in this tutorial could be blocking certain ports?

                  Thanks in advance!

                  This comment has been deleted

                    This post is outdated.

                    You need to install node v0.10.40

                    and on file /etc/init/todos.conf add a ’ in all exports

                    # upstart service file at /etc/init/todos.conf
                    description "Meteor.js (NodeJS) application"
                    author "Daniel Speichert <daniel@speichert.pro>"
                    
                    # When to start the service
                    start on started mongodb and runlevel [2345]
                    
                    # When to stop the service
                    stop on shutdown
                    
                    # Automatically restart process if crashed
                    respawn
                    respawn limit 10 5
                    
                    # we don't use buil-in log because we use a script below
                    # console log
                    
                    # drop root proviliges and switch to mymetorapp user
                    setuid todos
                    setgid todos
                    
                    script
                        export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
                        export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
                        # set to home directory of the user Meteor will be running as
                        export PWD=/home/todos
                        export HOME=/home/todos
                        # leave as 127.0.0.1 for security
                        export BIND_IP='127.0.0.1'
                        # the port nginx is proxying requests to
                        export PORT='8080'
                        # this allows Meteor to figure out correct IP address of visitors
                        export HTTP_FORWARDED_COUNT=1
                        # MongoDB connection string using todos as database name
                        export MONGO_URL='mongodb://localhost:27017/todos'
                        # The domain name as configured previously as server_name in nginx
                        export ROOT_URL='https://todos.net'
                        # optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
                        export METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
                        # this is optional: http://docs.meteor.com/#email
                        # commented out will default to no email being sent
                        # you must register with MailGun to have a username and password there
                        # export MAIL_URL=smtp://postmaster@mymetorapp.net:password123@smtp.mailgun.org
                        # alternatively install "apt-get install default-mta" and uncomment:
                        # export MAIL_URL=smtp://localhost
                        exec node /home/todos/bundle/main.js >> /home/todos/todos.log
                    end script
                    

                    I have seen about a million of these deploy to droplets guides. Does anyone have a guide to deploy an app from cloud9? I am on a pc, so not a mac, all of these terminal guides are great for people with a mac but what about the pc? I have all the contents of the app also on github. Also there should be something that says this is on terminal. This is on the server. Some parts say on Droplet but that’s it. Please help me out I have been searching for about a month on how to do this on a windows computer. I am about to try and rebuild my whole app on a my gf’s mac just so I can deploy it.

                    TL:DR? I have an app on Cloud 9 and can’t find a guide on how to deploy my app to Digitalocean Droplet.

                    I’ve followed these instructions and, like another post, I received an “Unknown Job” error. I’m using METEOR@1.2.1, which requires nodejs-0.10.40 based on the error logs. The “add-apt-repository ppa:chris-lea/node.js” command installs the PPA, but with Nodejs-0.10.37. I attempted to upgrade to nodejs-0.10.40, but the upgrade installed nodejs-0.10.43, which fails because of numerous deprecations.

                    I’m also confused about the difference between node and nodejs. When I install Meteor normally, it installs node-0.10.40. Specifically, on my Ubuntu server, executing the following commands return the associated results:

                    $ node -v this command returns 0.10.40 $ nodejs -v this command returns 0.10.43

                    QUESTIONS:

                    1. What is the difference between node and nodejs?
                    2. How do I get the “add-apt-repository ppa:chris-lea/node.js” command install nodejs-0.10.40 ?

                    Any direction is greatly appreciated.

                    Regards… Jim

                    This is a great article, and still applies today. I just successfully deployed a Meteor app using it this morning. But I did notice that one thing is now a little outdated: In the guide, the step where you create the meteor bundle file, you say execute:

                    meteor build .
                    

                    to get a todos.tar.gz file. With newer versions of the Meteor CLI tooling, you need to instead use:

                    meteor bundle todos.tar.gz
                    

                    Everything else is the same.

                    The link to meteor todo app tutorial is outdated on the introduction.You might want to update it to this.

                    https://www.meteor.com/tutorials

                    Great article. If I use a single droplet (the basic one) and I have a nginx and my meteor instance on this machine, do I need to set up nginx upstream module for sticky sessions? I don’t see it in this article.

                    The step to install node needs to be updated. The nodejs version installed here is too old for latest meteor.

                    I followed the first answer here to install latest nodejs: http://askubuntu.com/questions/594656/how-to-install-the-latest-versions-of-nodejs-and-npm-for-ubuntu-14-04-lts

                    I am getting this error.

                    start: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused

                    I follow word for word, with a few changes because they werent up to date, ie new nodejs, the way to cat the certs (used .crt not .pem) Do help! Im reading Upstart is outdated and people are using sytemdm or whatever and I’ve no clue on what’s going on. Lol

                    I created a user here just to tell u that there is no way in hell i am trying this 2 year old long tutorial that will 100% fail and ruin my day (no offense to the creator)

                    Please make a easy to use tool or update/shorten this tutorial.

                    From what i see DigitalOcean is a good option for meteor apps, but deployment is just pure pain and errors.

                    Same here.

                    Same here, for couple of days, I am trying to run my meteor app :/

                    Is this tutorial up-to-date?

                    how can i set the read preference to secondary ?

                    im using this in my forever service which is not working for me. export MONGO_URL=mongodb://10.xx.xx.xxx:27017,10.xx.xx.xxx:27017/Chat replicaSet=rs1&readPreference=seconday

                    Hey — the cache block on this nginx config can cause problems if your meteor app uses a router and people access it via direct links.

                    you can replace this:

                            if ($uri != '/') {
                                expires 30d;
                            }
                    

                    with this:

                        if ($request_filename ~* .(js|css)$ ) {
                            expires 30d;
                        }
                    

                    thereby explicitly only caching js and css files. Because meteor’s build step gives these unique filenames every time, you make sure you never get a cached html wrapper (which could point to an old code bundle!)

                    Join the Tech Talk
                    Success! Thank you! Please check your email for further details.

                    Please complete your information!

                    Become a contributor for community

                    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                    DigitalOcean Documentation

                    Full documentation for every DigitalOcean product.

                    Resources for startups and SMBs

                    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                    Get our newsletter

                    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                    New accounts only. By submitting your email you agree to our Privacy Policy

                    The developer cloud

                    Scale up as you grow — whether you're running one virtual machine or ten thousand.

                    Get started for free

                    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                    *This promotional offer applies to new accounts only.