Meteor UP
Meteor has a convenient bundle feature for packaging your apps into a tarball for deployment, but you still need to manage the files and upstart on your remote host. Meteor Up (MUP) does this for us so you get logs, start/stop/status and environment vars, it is all controlled from your local machine.
Like most of my posts this is more or less notes I've kept from various sources and my own experience.
Install MUP
Install MUP on your local computer through NPM.
npm install -g mup
MUP setup
In you local project directory
mup init
Which generates a mup.json file like this:
{
// Server authentication info
"servers": [
{
"host": "<remote server addr>",
"username": "root",
//"password": "password"
// or pem file (ssh based authentication)
"pem": "~/.ssh/id_rsa"
}
],
// Install and configure MongoDB on remote server.
"setupMongo": false,
// Install Node.js on the server which is required
"setupNode": false,
// Configure your Node version number, stick with this for the moment.
"nodeVersion": "0.10.36",
// Install Phantom.js on the server
"setupPhantom": false,
// App name (No spaces)
"appName": "<appname>", //this is used as the dir name to store your app under /opt/
// Location of app (local directory)
"app": "<local path to your meteor project>",
// Configure environment vars you want to pass into your running app from the CLI
"env": {
"ROOT_URL": "http://<remote server ip>:<remote port>",
"PORT": "<remote port>",
"MONGO_URL": "mongodb://<remote MongoDB >"
},
// Meteor Up checks if the app comes online just after the deployment
// before mup checks that, it will wait for no. of seconds configured below
"deployCheckWaitTime": 15
}
MUP can configure Mongo on your remote server, the above guide is for a 3rd party Mongo host
Setup the remote enviornment. Uses the above settings to install and anything required and setup directories.
mup setup
keys
You'll get sick of typing your password each time you make a change so it's recommended you use keys to authenticate. On your remote server add yourself to sudoers without password.
sudo visudo
Add yourself:
<your username> ALL=(ALL) NOPASSWD:ALL
If you don't already have local rsa keys create a new one:
ssh-keygen -t rsa -c "<your email address>"
Use the default key storage and don't use a passphrase just leave it blank.
Then copy the public key from your remote server to your local dev pc. Output the key contents with:
cat ~/.ssh/id.rsa.pub
then copy and paste it into remote file:
vi ~/.ssh/authorized_keys
deploy
When your project is ready to deploy make sure you have initialized MUP, configured the mup.json file, then setup your remote enviornment with MUP setup before deploying with:
mup deploy
It will use Meteor's bundle command, upload the resulting app to your remote host into /opt/
Build mobile app
Not a MUP thing but you need to point your mobile app to the remote host when building it with Meteor.
meteor run android-device --mobile-server ip:port
You can read more about it here Meteor mobile deployment
CORS
With your app running on mobile devices (android/ios) the remote server will prevent access to it's resources by default, you need to allow Cross-origin Resource Sharing.
if(Meteor.isServer){
Meteor.startup(function () {
WebApp.connectHandlers.use(function (req, res, next) {
res.setHeader('access-control-allow-origin', '*');
return next();
})
})
}
Keep MUP upto date
npm update mup -g
Reconfig application MUP settings
Anytime you change mup.json you need to apply any changes to your remote server
mup reconfig
Multiple domains
MUP makes it easy to deploy and manage multiple apps on a single server remotely. If you want each one to have it's own sub-domains you need to configure a reverse proxy to handle the requests.
For this example I'm using Ubuntu 14.
Install Nginx
sudo apt-get install nginx
Configure Nginx
copy the default configuration for each app you have a domain for, then edit the file
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/<appname>
vi /etc/nginx/sites-available/<appname>
There are many settings in here but we just want to tell it to listen for our domain and point it to our app where Meteor is running. Configure Server similar to this:
server {
listen 80;
server_name <app domain> <public ip:port>;
access_log /var/log/nginx/<appname>.access.log;
error_log /var/log/nginx/<appname>.error.log;
location / {
proxy_pass http://<internal ip:port>;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Test the configuration file with
nginx -t
Restart Nginx
nginx -s reload
Accessing your domain should now redirect the request to your app.
FAQ
Q
How do I troubleshoot?
A
Monitor the logs for your app live
mup logs -f
Q
mup deploy returns an error:
curl: (52) Empty reply from server
...
Waitinting for MongoDB to initialize
A
Check the logs, but somethings to check:
Try serving up your Meteor app localy to see if it's your app or environment.
Has your MongoDB instance gone to sleep? The Compose sandbox can goto sleep.
Is remote server using Node version atleast same nodeVersion in mup.json? You can manage node versions with 'n':
npm install -g n
Try extending deployCheckWaitTime in mup.json.
Q
I'm using Meteor accounts package and the MUP log reveals
Could not load the binding file, Tried:
app/programs/server/npm/npm-bcrypt/node_modules/bcrypt/build/bcrypt_lib.node
A
Try adding to packages.json in your local meteor project directory under .meteor/local/build/programs/
{
"dependencies": {
"bcrypt": "0.5.~"
}