Meteor JS is undoubtedly a great framework that makes it very fast to learn and prototype. However, the downfall of the framework is when we try to move it to production, the documentation is scarce. This is also a problem we faced when we try to migrate our code for production. There are a few things to note before releasing Meteor App for production:
- Remove Insecure
- Remove Autopublish
- Make sure that Meteor JS environment variables are set correctly
Meteor comes installed with
insecure package which makes development quick. It allows the client-side to edit (only insert, update and delete) database directly without writing any codes on the server-side but when you are moving your app to production, it should be removed for security reasons. Once this package is removed, you no longer able to use
remove() methods from the collections API, instead you need to move that part of the code to the server-side's
Meteor.method() function and on the client-side, replace it with
Meteor.call() function. For more information on how it can be achieved, please refer to this Meteor Tutorial
insecure package, this is also installed on Meteor's fresh installation. However, it does not involve any database editing features, instead, this package is about the database's
find() method. Once this package is removed, your app's
find() method no longer works, you have to add
Meteor.subscribe() method on the client-side and
Meteor.publish() on the server-side. What I found making this feature confusing is its naming of the methods, it uses the same Model.find() method on the client.
This feature is when the controller changes, it will request a subset of the data to be stored on the client-side, so when
Model.find() is called on the client-side, it is actually querying the data that is stored within client. If you have conditions that filter the data by field on the client-side, make sure that those fields are also selected on the server-side
publish() method. For more information on how to migrate to publish/subscribe method, please refer to this tutorial.
Meteor JS Environment Variables
autopublish package, it also comes with a feature called Hot Code Push. This is a feature that when you changed your template, Meteor JS will push the update to all clients. This makes it convenient for updating the clients, but makes debugging hard if you don’t know this feature is enabled by default. We have had this issue when we first deployed the app on Digital Ocean as we followed the deployment guides available through the Internet. Symptoms we encountered were:
- When the application is first launched (launch after a fresh installation), the screen seems to refresh automatically.
- Once it the screen refreshed, the app no longer able to contact the server.
This is due to Meteor Cordova's
Hot Code Push pushing new codes the client, once it gets the new code, it refreshes the screen. This is supposed to happen only when I rebuilt the application, not for every clients. To prevent this, environment variable
AUTOUPDATE_VERSION needs to be set, if it's changed, an update will be sent to the client. For more information about
AUTOUPDATE_VERSION please refer to the FAQ
Hot Code Push feature also allow the update to the server's URL, this is a handy feature for migration of the server. However, it is also required that the
ROOT_URL environment variable to be set correctly on the server-side, it is what we have encountered with our application. After 1 whole day of debugging trying to figure out what went really wrong, we finally figured that it is this environment variable that is misconfigured. If you are not migrating to a new server, make sure that
ROOT_URL is the same as
--server parameter you used to build the app. For more information about this issue, please refer to this Github issue
My Final Upstart Configuration
#upstart service file at /etc/init/meteor-service.conf description "Meteor.js (NodeJS) application for eaxmple.com:3000" author "firstname.lastname@example.org" # When to start the service start on runlevel  # When to stop the service stop on shutdown # Automatically restart process if crashed respawn respawn limit 10 5 # Essentially lets upstart know the process will detach itself to the background expect fork # drop root proviliges and switch to mymetorapp user setuid <user> setgid <user> script export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' export NODE_BIN='/usr/local/bin' export PORT=3000 # this allows Meteor to figure out correct IP address of visitors export HTTP_FORWARDED_COUNT=1 export MONGO_URL=mongodb://<mongo User>:<mongo password>@127.0.0.1:27017/<mongo DB> export ROOT_URL=https://<domain> # this is for hot code push export AUTOUPDATE_VERSION=0.0.1 exec node ~/bundle/main.js >> ~/meteor.log end script