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!
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.
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.
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)
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)
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.
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:
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:
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:
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.
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):
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!
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.
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:
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:
 Evented I/O for V8 javascript. Node's goal is to provide an easy way to build scalable network programs
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:
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.
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.
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:
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:
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:
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:
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:
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.