How to deploy MeteorJS app to your server Meteor JS 14.06.2016

meteor_deployment.png

My local environment is Arch Linux and git repository for passing code to server (Ubuntu). For git hosting I use gitolite. My project structure on server is following

  • config directory for nginx, supervisord, etc
  • rep directory for git repository
  • uploads directory for uploaded files
  • www directory for build version of project
  • build.sh script for build
  • env.sh script with environment variables
  • settings.json meteor's settings for project

Let's install Node.JS v5 on server

curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -

Clone the project to /path/project/rep

git clone -v ssh://git@localhost:port/project.git /path/project/rep

Build project

# cd /path/project/rep
meteor build --architecture os.linux.x86_64 --directory /path/project/www

Install packages

cd /path/project/www/bundle/programs/server && npm install

Setup environment

#cd /path/project/
#vim env.sh
export PORT=3000
export MONGO_URL=mongodb://localhost:27017/meteor
export ROOT_URL=http://example.com
export METEOR_SETTINGS="`(cat settings.json)`"

Nginx config file

# vim /path/project/config/nginx.conf

location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
} 

Important part of meteor's deployment is tool for restarting the application if it crashes or restarting your node application as a service every time you restart the server. For this purposes you can use PM2 or supervisord.

Let's install PM2, which is a process manager for Node.JS applications. PM2 provides an easy way to manage and daemonize applications (run them as a service).

The latest PM2 stable version is installable via NPM

sudo npm install pm2@latest -g

The simplest way to start, daemonize and monitor your application is as simple as following command

pm2 start app.js

# or for meteor app
# cd /path/project/www/bundle
pm2 start main.js --name "MyProject"
pm2-list.png

PM2 maintains information, such as the PID of the process, its current status, and memory usage.

Once your application is running all you have to do to stop it is

pm2 stop MyProject

When there is new code again it is very simple

pm2 reload MyProject

If you are encountering issues, don't forget to execute the log command to help you debugging

pm2 logs

View logs for one of your apps

pm2 logs MyProject

If you want to display more details about an app, use the following command

pm2 show MyProject

To delete your app just enter this command with the app name

pm2 delete MyProject

Command to restarting your app is

pm2 restart MyProject

Show all running apps and their status

pm2 list

Applications that are running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot).

The startup subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots. You must also specify the init system you are running on, ubuntu, in our case:

sudo su -c "env PATH=$PATH:/usr/bin pm2 startup ubuntu -u www --hp /home/www"

The platform can be any one of the following: ubuntu, centos, redhat, gentoo, systemd, darwin, amazon.

After ensuring that your app is currently running, instruct PM2 to save all running processes so that it can remember and resurrect them after a server reboot.

pm2 save

PM2 allows you to define your app’s configuration within a JSON file. This way, you don’t need to type and remember the commands when updating or starting new apps. The complete configuration is stored within the JSON file.

Final step is automation of building process via build.sh script

#! /bin/bash

PROJECT_NAME=wishlist
PROJECT_PATH=~www/wishlist

echo -e "\n\e[31mSTOPPING\e[0m\n"

pm2 stop $PROJECT_NAME
rm -rf $PROJECT_PATH/www
mkdir $PROJECT_PATH/www
cd $PROJECT_PATH/rep

echo -e "\n\e[31mGIT PULL\e[0m\n"

git pull

echo -e "\n\e[31mBUILDING ...\e[0m\n"

meteor build --architecture os.linux.x86_32 --directory $PROJECT_PATH/www
cd $PROJECT_PATH/www/bundle/programs/server 

echo -e "\n\e[31mNPM INSTALL\e[0m\n"

npm install
source $PROJECT_PATH/env.sh 

echo -e "\n\e[31mSTARTING\e[0m\n"

pm2 start $PROJECT_NAME
echo -e "\e[32mDONE\e[0m"

That's is all.

Some useful hints

If you are using meteorhacks/npm then add following strings to main .gitignore

.packages/
!.packages/npm-container/index.js
!.packages/npm-container/package.js

If you are using email package for mail sending you have following exception TypeError: Cannot assign to read only property 'reconnectCount' of false. It's because meteor use old version of Simplesmtp, bug report #6529.

To solve this you should manually (or add to build.sh script) delete Simplesmtp and install another version

rm -rf PROJECT_PATH/www/bundle/programs/server/npm/node_modules/meteor/email/node_modules/simplesmtp
cd PROJECT_PATH/www/bundle/programs/server/npm/node_modules/meteor/email/node_modules/
npm install simplesmtp@0.3.34