├── install ├── nodeproxy.js ├── README.md └── deploymeteor.sh /install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | INSTALL_DIR="$HOME/.deploymeteor" 4 | 5 | if [ ! -d "$INSTALL_DIR" ]; 6 | then 7 | git clone http://github.com/aldeed/deploymeteor.git "$INSTALL_DIR" 8 | else 9 | cd "$INSTALL_DIR" 10 | git pull 11 | fi 12 | 13 | if [ ! -f /usr/local/bin/deploymeteor ]; 14 | then 15 | sudo ln -s "$INSTALL_DIR/deploymeteor.sh" /usr/local/bin/deploymeteor 16 | fi -------------------------------------------------------------------------------- /nodeproxy.js: -------------------------------------------------------------------------------- 1 | var httpProxy = require('http-proxy'), 2 | http = require('http'), 3 | fs = require('fs'); 4 | 5 | var nodeProxyDir = __dirname; 6 | var map = {}; 7 | fs.readdir(nodeProxyDir, function(err, files) { 8 | if (err) { 9 | console.log('Error: ' + err); 10 | return; 11 | } 12 | 13 | for (var i = 0, ln = files.length, file, data; i < ln; i++) { 14 | file = files[i]; 15 | if (file.slice(-5) === '.json') { 16 | data = fs.readFileSync(nodeProxyDir + '/' + file, 'utf8'); 17 | data = JSON.parse(data); 18 | for (var name in data) { 19 | map[name] = data[name]; 20 | } 21 | } 22 | } 23 | 24 | //create proxy server 25 | var proxy = httpProxy.createProxyServer(); 26 | 27 | proxy.on('error', function (error, req, res) { 28 | var json; 29 | console.log('proxy error', error); 30 | if (!res.headersSent) { 31 | res.writeHead(500, { 'content-type': 'application/json' }); 32 | } 33 | 34 | json = { error: 'proxy_error', reason: error.message }; 35 | res.end(JSON.stringify(json)); 36 | }); 37 | 38 | //start proxy server 39 | var server = http.createServer(function(req, res) { 40 | proxy.web(req, res, { 41 | target: 'http://' + map[req.headers.host] 42 | }); 43 | }); 44 | 45 | // 46 | // Listen to the `upgrade` event and proxy the 47 | // WebSocket requests as well. 48 | // 49 | server.on('upgrade', function (req, socket, head) { 50 | proxy.ws(req, socket, head, { 51 | target: 'ws://' + map[req.headers.host] 52 | }); 53 | }); 54 | 55 | server.listen(80); 56 | 57 | console.log('Node Proxy Server started with:', map); 58 | // Downgrade the process to run as the ec2-user group and user now that it's bound to privileged ports. 59 | process.setgid('ec2-user'); 60 | process.setuid('ec2-user'); 61 | }); 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deploymeteor 2 | 3 | NOTE: I'm not maintaining this script, but I will accept pull requests if you are using it and would like to contribute fixes. I recommend that you check out [Meteor Up](https://github.com/arunoda/meteor-up), [Modulus](https://modulus.io/), [Docker/Kubernetes](https://bulletproofmeteor.com/architecture/deploying-meteor-apps-into-a-kubernetes-cluster), etc. 4 | 5 | The deploymeteor script makes it as easy as possible to deploy one or more meteor apps to a standard Amazon EC2 server running the latest Amazon Linux or Ubuntu AMI. It can be used to set up the server and to set up individual app environments on the server. Each app is hosted on a port that you specify, but the script also automatically sets up a node proxy server on port 80, which serves the correct app based on hostname. 6 | 7 | ## Install deploymeteor 8 | 9 | To install deploymeteor on your workstation (Mac or Linux), run this command in your terminal: 10 | 11 | ```bash 12 | $ sudo -H curl https://raw.githubusercontent.com/aldeed/deploymeteor/master/install | sh 13 | ``` 14 | 15 | ## Setting Up the Server 16 | 17 | 1. Launch a new EC2 server and make note of its hostname. You can deploy multiple meteor apps/websites to this one server. Make sure to enable SSH (port 22) and HTTP (port 80). You might want to open additional ports or port ranges for connecting directly to your meteor apps. 18 | 2. If your server is an Amazon Linux (not Ubuntu) AMI, SSH into the EC2 server and enter `sudo visudo`. Near the bottom, press I to switch to insert mode and insert a ! before `requiretty`. This is necessary for the deploymeteor script to work correctly. Press ESC and enter `:w!`. Now enter `:q` to quit. 19 | 3. On your workstation, open a Terminal session and enter `deploymeteor prepserver`. Answer the prompts. The host is the one you noted in step 1 and the key file is the one you downloaded while setting up the EC2 server. 20 | 21 | You may now use this server to host one or more meteor apps. You never need to run `deploymeteor prepserver` for this server again, but you may do so whenever you want to ensure that the server is running the latest versions of node, meteor, etc. 22 | 23 | ## Set Up the App for Deployment to an Environment 24 | 25 | Let's assume that you created a meteor app locally, and now you're ready to deploy it to your server. 26 | 27 | ```bash 28 | $ cd /my/app/directory 29 | $ deploymeteor 30 | ``` 31 | 32 | Replace <env> with whatever you want to call the environment (for example, test, staging, or prod), and then answer all the prompts. This environment will be created and initialized on the remote server and added as a remote repository for this git repository. 33 | 34 | You must have git installed locally before running this command, but you do not necessarily have to initialize a git repository in your app directory. If the current directory isn't already under git version control when you run deploymeteor, the script automatically initializes the git repo for you, adds all files, and does an initial commit. 35 | 36 | ## Deploying the App 37 | 38 | After you have run `deploymeteor ` once, you don't need to run it again for that app environment unless any of the information you provided in the prompts changes, for example, if your database or e-mail URLs need to change for that environment. 39 | 40 | It's now very easy to deploy the app: 41 | 42 | ```bash 43 | $ git push master 44 | ``` 45 | 46 | And when you make more changes to the local app files, simply commit your changes and run that same command again: 47 | 48 | ```bash 49 | $ git commit -a -m "I updated my app" 50 | $ git push master 51 | ``` 52 | 53 | ## Additional Options 54 | 55 | There are several additional options that allow you to quickly perform actions for a certain app environment from your workstation. 56 | 57 | ### deploymeteor logs 58 | 59 | Shows you the `out`, `error`, and `forever` logs for a certain app environment or for all app environments hosted on a single server at once. 60 | 61 | ```bash 62 | $ cd /my/app/directory 63 | $ deploymeteor logs 64 | ``` 65 | 66 | Or 67 | 68 | ```bash 69 | $ cd /any/app/directory 70 | $ deploymeteor logs all 71 | ``` 72 | 73 | ### deploymeteor clearlogs 74 | 75 | Clears the `out`, `error`, and `forever` logs for a certain app environment or for all app environments hosted on a single server at once. 76 | 77 | ```bash 78 | $ cd /my/app/directory 79 | $ deploymeteor clearlogs 80 | ``` 81 | 82 | Or 83 | 84 | ```bash 85 | $ cd /any/app/directory 86 | $ deploymeteor clearlogs all 87 | ``` 88 | 89 | ### deploymeteor restart 90 | 91 | Restarts (or starts) a certain app environment or all app environments hosted on a single server at once. 92 | 93 | ```bash 94 | $ cd /my/app/directory 95 | $ deploymeteor restart 96 | ``` 97 | 98 | Or 99 | 100 | ```bash 101 | $ cd /any/app/directory 102 | $ deploymeteor restart all 103 | ``` 104 | 105 | Tip: If you need to reboot your EC2 instance for any reason, run `deploymeteor restart all` after it restarts and everything should be back to normal. 106 | 107 | ### deploymeteor restartproxy 108 | 109 | Restarts (or starts) the nodeproxy app, which is what routes traffic to the correct app/port based on hostname. Generally speaking, there's no reason for you to run this. 110 | 111 | ### deploymeteor stop 112 | 113 | Stops a certain app environment. 114 | 115 | ```bash 116 | $ cd /my/app/directory 117 | $ deploymeteor stop 118 | ``` 119 | 120 | ## What Exactly Does the Script Do? 121 | 122 | ### deploymeteor prepserver 123 | 124 | Connects to the EC2 server using SSH and then: 125 | 126 | 1. Installs or upgrades Git to the latest version. 127 | 2. Installs or upgrades Node to the latest version. 128 | 3. Installs or upgrades Forever to the latest version. 129 | 4. Installs or upgrades Meteor to the latest version. 130 | 5. Installs or upgrades Meteorite to the latest version. 131 | 6. Installs or upgrades the node http-proxy package to the latest version. 132 | 7. Copies nodeproxy.js to the server. 133 | 134 | ### deploymeteor <environment> 135 | 136 | 1. Prompts you for the root URL for the environment, the port on which it should be hosted, the MongoDB URL, and the SMTP URL. These are the same environment variable values you would enter when launching Meteor as per their documentation. 137 | 2. Initializes git in the local directory if you haven't already done so. 138 | 3. Creates necessary directories on the EC2 server. Your apps are automatically stored in ~/meteorapps/[appname]/[environmentname]. 139 | 4. Initializes a bare git repository on the EC2 server. 140 | 5. Creates a custom post-receive hook for this git repository on the EC2 server. 141 | 6. Creates a file on the EC2 server that maps your app's hostname to its port. This file is used by nodeproxy.js. 142 | 7. Starts or restarts the nodeproxy.js node app on the EC2 server, causing the new file to be read and parsed. 143 | 8. Sets up a new remote in your local git directory. This remote is named based on the environment name you specified. 144 | 145 | ### git push <environment> master 146 | 147 | Whenever you push your changes to the new remote that was set up, the post-receive hook script automatically runs on the EC2 server. It does the following: 148 | 149 | 1. Copies the latest versions of all the app files to a secondary directory. 150 | 2. Runs `meteor bundle` to create the node bundle, and then immediately extracts the archive file. 151 | 3. Reinstalls `fibers` in the extracted bundle. 152 | 4. Copies the node app to another directory from which it will run. 153 | 5. Starts or restarts the app using Node and Forever. It is bound to the port you specified, but it is also accessible through port 80 based on using the hostname you provided (the root URL minus protocol). 154 | 155 | ## What About SSL? 156 | 157 | If you want to secure an app environment using an SSL certificate, you can do it by using a load balancer: 158 | 159 | 1. When you are prompted for the root URL, make sure to enter a URL that begins with `https://` 160 | 2. Set up an Elastic Load Balancer (ELB) in Amazon EC2. In the ELB settings, choose to forward HTTPS (port 443) to HTTP (port 80). Provide your SSL certificate (single domain or wildcard). 161 | 3. If the app is hosted on a subdomain, then just create a CNAME record in your DNS settings, and point to the DNS address of the ELB. If the app is a root domain, you'll need to use an A record instead of CNAME, but you can only do that if you use Route53 DNS through Amazon, in which case you can use an A record ALIAS. 162 | 163 | If you need to use multiple SSL certificates (because you're hosting multiple root domains or you don't have a wildcard certificate), then you'll need to set up one ELB per certificate. They can all forward to port 80 on the same EC2 instance, though. The AWS Console may or may not let you select an EC2 instance that already has a load balancer. If it does not, you can still do it, but you'll have to use the CLI or API. 164 | 165 | ## Thanks 166 | 167 | Thanks to @julien-c for inspiration in [meteoric.sh](https://github.com/julien-c/meteoric.sh) and credit to [this post](http://toroid.org/ams/git-website-howto). 168 | 169 | [![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/aldeed/) 170 | -------------------------------------------------------------------------------- /deploymeteor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=`pwd` 4 | APP_NAME=${PWD##*/} 5 | 6 | if [ -z "$1" ]; then 7 | echo 8 | echo "Usage: deploymeteor " 9 | echo "For example, type deploymeteor staging to deploy to a staging environment. This environment will be created and initialized on the remote server and added as a remote repository for this git repository." 10 | echo 11 | echo "Before the first time you use deploymeteor with a new server, you should also run deploymeteor prepserver. This will install node, npm, meteor, forever, and meteorite on the server." 12 | exit 1 13 | fi 14 | 15 | #If this has been run before, grab variable defaults from stored config file 16 | if [ -r "$PWD/.deploymeteor.config" ]; then 17 | source "$PWD/.deploymeteor.config" 18 | fi 19 | 20 | #prompt for info needed by both prepserver and environment deploy 21 | echo 22 | echo "Enter the hostname or IP address of the EC2 server." 23 | echo "Examples: 11.111.11.111 or ec2-11-111-11-111.us-west-2.compute.amazonaws.com" 24 | if [ -z "$LAST_APP_HOST" ]; then 25 | echo "Default (press ENTER): No default" 26 | else 27 | echo "Default (press ENTER): $LAST_APP_HOST" 28 | fi 29 | read -e -p "Host: " APP_HOST 30 | APP_HOST=${APP_HOST:-$LAST_APP_HOST} 31 | 32 | DEFAULT_DISTRO='amazon' 33 | echo 34 | echo "Enter the AMI type (of Linux)" 35 | echo "Examples: ubuntu or amazon" 36 | if [ -z "$LAST_DISTRO" ]; then 37 | echo "Default (press ENTER): $DEFAULT_DISTRO" 38 | else 39 | echo "Default (press ENTER): $LAST_DISTRO" 40 | fi 41 | read -e -p "Distro: " DISTRO 42 | DISTRO=$(echo ${DISTRO:-$LAST_DISTRO} | tr A-Z a-z) 43 | 44 | # Use known Amazon defaults for usernames (defaulting to Amazon Linux style) 45 | case "$DISTRO" in 46 | 'ubuntu') REMOTE_USER='ubuntu' ;; 47 | *) REMOTE_USER='ec2-user' ;; 48 | esac 49 | REMOTE_HOME="/home/$REMOTE_USER" 50 | SCRIPTPATH="$HOME/.deploymeteor" 51 | # Trailing slash prevents scp renaming script if initial setup went wrong... 52 | NODEPROXY_DIR=$REMOTE_HOME/nodeproxy/ 53 | APPS_DIR=$REMOTE_HOME/meteorapps 54 | 55 | echo 56 | echo "Enter the path to your EC2 .pem file on this machine." 57 | if [ -z "$LAST_EC2_PEM_FILE" ]; then 58 | echo "Default (press ENTER): No default" 59 | else 60 | echo "Default (press ENTER): $LAST_EC2_PEM_FILE" 61 | fi 62 | read -e -p "Key file: " EC2_PEM_FILE 63 | EC2_PEM_FILE=${EC2_PEM_FILE:-$LAST_EC2_PEM_FILE} 64 | 65 | #store answers to use as defaults the next time deploymeteor is run 66 | cat > $PWD/.deploymeteor.config < /dev/null 93 | 94 | #install node 95 | echo "Installing Node and NPM..." 96 | sudo yum install -q -y npm --enablerepo=epel &> /dev/null 97 | #install nvm 98 | echo "Installing or updating NVM..." 99 | sudo -H npm install -g nvm &> /dev/null 100 | fi 101 | 102 | 103 | #install forever 104 | echo "Installing or updating Forever..." 105 | sudo -H npm install -g forever &> /dev/null 106 | 107 | #install meteor 108 | echo "Installing or updating Meteor..." 109 | curl https://install.meteor.com | /bin/sh 110 | 111 | #install meteorite 112 | echo "Installing or updating Meteorite..." 113 | sudo -H npm install -g meteorite &> /dev/null 114 | 115 | #install http-proxy 116 | echo "Installing or updating http-proxy..." 117 | mkdir -p $NODEPROXY_DIR 118 | cd $NODEPROXY_DIR 119 | npm install http-proxy &> /dev/null 120 | 121 | #add nvm node versions to path 122 | if grep -q "./node_modules/.bin" <<< "$PATH" ; then 123 | echo "./node_modules/.bin found in PATH" 124 | else 125 | echo "./node_modules/.bin not found in PATH. Adding it to PATH." 126 | export PATH=./node_modules/.bin:$PATH 127 | fi 128 | if grep -q "./node_modules/.bin" ~/.bashrc ; then 129 | echo "./node_modules/.bin found in ~/.bashrc" 130 | else 131 | echo "./node_modules/.bin not found in ~/.bashrc. Adding it in ~/.bashrc." 132 | echo "export PATH=./node_modules/.bin:$PATH" >> ~/.bashrc 133 | fi 134 | EOL 135 | # Copy nodeproxy.js from script directory to server 136 | # We don't need to start it until an environment has been deployed 137 | echo "Copying nodeproxy.js to the server..." 138 | scp $SSH_OPT $SCRIPTPATH/nodeproxy.js $SSH_HOST:$NODEPROXY_DIR &> /dev/null 139 | echo "Done!" 140 | exit 1 141 | ;; 142 | logs) 143 | if [ -z "$2" ]; then 144 | echo 145 | echo "Usage: deploymeteor logs or deploymeteor logs all" 146 | exit 1; 147 | fi 148 | if [ $2 = "all" ]; then 149 | ssh -t $SSH_OPT $SSH_HOST < or deploymeteor clearlogs all" 189 | exit 1; 190 | fi 191 | if [ $2 = "all" ]; then 192 | ssh -t $SSH_OPT $SSH_HOST < /dev/null 230 | sudo forever start -l $NODEPROXY_DIR/logs/forever.log -o $NODEPROXY_DIR/logs/out.log -e $NODEPROXY_DIR/logs/err.log -a -s $NODEPROXY_DIR/nodeproxy.js 231 | EOL3 232 | echo "Done!" 233 | exit 1 234 | ;; 235 | restart) 236 | if [ -z "$2" ]; then 237 | echo 238 | echo "Usage: deploymeteor restart or deploymeteor restart all" 239 | exit 1; 240 | fi 241 | if [ $2 = "all" ]; then 242 | ssh -t $SSH_OPT $SSH_HOST < /dev/null 255 | sudo forever start -l $NODEPROXY_DIR/logs/forever.log -o $NODEPROXY_DIR/logs/out.log -e $NODEPROXY_DIR/logs/err.log -a -s $NODEPROXY_DIR/nodeproxy.js &> /dev/null 256 | echo "Done" 257 | EOL8 258 | else 259 | ssh -t $SSH_OPT $SSH_HOST <" 274 | exit 1; 275 | fi 276 | ssh -t $SSH_OPT $SSH_HOST < /dev/null 278 | EOL7 279 | echo "Stopped the $2 environment of $APP_NAME" 280 | exit 1 281 | ;; 282 | esac 283 | 284 | ####The rest is run only for setting up git deployment#### 285 | APP_DIR=$APPS_DIR/$APP_NAME/$1 286 | 287 | #If this has been run before, grab variable defaults from stored config file 288 | if [ -r "$SCRIPTPATH/.settings.$APP_NAME.$1" ]; then 289 | source "$SCRIPTPATH/.settings.$APP_NAME.$1" 290 | fi 291 | 292 | #Defaults 293 | DEFAULT_ROOT_URL=${DEFAULT_ROOT_URL:-http://$APP_HOST} 294 | DEFAULT_PORT=${DEFAULT_PORT:-8000} 295 | DEFAULT_NODE_VERSION=${DEFAULT_NODE_VERSION:-0.10.29} 296 | 297 | #Prompt for additional app-specific info that is needed 298 | echo 299 | echo "Enter the version of NodeJS that you want to use." 300 | echo "Example: 0.10.29" 301 | echo "Default (press ENTER): $DEFAULT_NODE_VERSION" 302 | echo 303 | read -e -p "NodeJS Version: " NODE_VERSION 304 | NODE_VERSION=${NODE_VERSION:-$DEFAULT_NODE_VERSION} 305 | echo 306 | echo "Enter the root URL for this website, as users should access it, including protocol." 307 | echo "Examples: http://mysite.com or https://mysite.com" 308 | echo "Default (press ENTER): $DEFAULT_ROOT_URL" 309 | echo 310 | read -e -p "Root URL: " ROOT_URL 311 | ROOT_URL=${ROOT_URL:-$DEFAULT_ROOT_URL} 312 | echo 313 | echo "Enter the port on which to host this website. Do not enter 80 because a proxy server is automatically launched on that port." 314 | echo "Examples: 8080 or 3001" 315 | echo "Default (press ENTER): $DEFAULT_PORT" 316 | echo 317 | read -e -p "Port: " PORT 318 | PORT=${PORT:-$DEFAULT_PORT} 319 | echo 320 | echo "Enter the URL for the MongoDB database used by this app." 321 | echo "Format: mongodb://:@:/" 322 | echo "Default (press ENTER): $DEFAULT_MONGO_URL" 323 | read -e -p "MongoDB URL: " MONGO_URL 324 | MONGO_URL=${MONGO_URL:-$DEFAULT_MONGO_URL} 325 | echo 326 | echo 327 | echo "Enter the SMTP URL for e-mail sending by this app." 328 | echo "Format: smtp://:@:" 329 | echo "Default (press ENTER): $DEFAULT_MAIL_URL" 330 | read -e -p "E-mail URL: " MAIL_URL 331 | MAIL_URL=${MAIL_URL:-$DEFAULT_MAIL_URL} 332 | echo 333 | echo 334 | echo "Enter the local path to a settings JSON file for this app environment." 335 | echo "Format: /path/to/settings.json" 336 | echo "Default (press ENTER): $DEFAULT_SETTINGS_FILE" 337 | read -e -p "Settings file path: " SETTINGS_FILE 338 | SETTINGS_FILE=${SETTINGS_FILE:-$DEFAULT_SETTINGS_FILE} 339 | echo 340 | 341 | ##support there being no mongo or mail url 342 | if [ -z "$MONGO_URL" ]; then 343 | MONGO_URL_SETTER="" 344 | else 345 | MONGO_URL_SETTER=" MONGO_URL=$MONGO_URL" 346 | fi 347 | 348 | if [ -z "$MAIL_URL" ]; then 349 | MAIL_URL_SETTER="" 350 | else 351 | MAIL_URL_SETTER=" MAIL_URL=$MAIL_URL" 352 | fi 353 | 354 | if [ -z "$SETTINGS_FILE" ]; then 355 | SETTINGS_SETTER="" 356 | else 357 | if [ -r "$SETTINGS_FILE" ]; then 358 | SETTINGS_SETTER=" METEOR_SETTINGS=\$(cat $APP_DIR/settings.json)" 359 | else 360 | SETTINGS_SETTER="" 361 | SETTINGS_FILE="" 362 | fi 363 | fi 364 | 365 | #store answers to use as defaults the next time deploymeteor is run 366 | if [ -r "$SCRIPTPATH/.settings.$APP_NAME.$1" ]; then 367 | cat > $SCRIPTPATH/.settings.$APP_NAME.$1 < $SCRIPTPATH/.settings.$APP_NAME.$1 < /dev/null 410 | git add . &> /dev/null 411 | git commit -a -m "Initial commit" &> /dev/null 412 | fi 413 | echo "Setting up git deployment for the $1 environment of $APP_NAME" 414 | ssh -t $SSH_OPT $SSH_HOST < /dev/null 419 | mkdir -p $GIT_APP_DIR/hooks 420 | mkdir -p $WWW_APP_DIR 421 | mkdir -p $LOG_DIR 422 | mkdir -p $BUNDLE_DIR 423 | # Init the bare git repo 424 | echo "Setting up the bare git repository on the EC2 server..." 425 | cd $GIT_APP_DIR 426 | git init --bare &> /dev/null 427 | # Create the post-receive hook file and set its permissions; we'll add its contents in a bit 428 | touch hooks/post-receive 429 | sudo chmod +x hooks/post-receive 430 | # Create/update the JSON file for this environment used by nodeproxy.js 431 | echo "Updating hostname mapping for nodeproxy..." 432 | cd $NODEPROXY_DIR 433 | cat > $APP_NAME.$1.json < /dev/null 445 | sudo forever start -l $NODEPROXY_DIR/logs/forever.log -o $NODEPROXY_DIR/logs/out.log -e $NODEPROXY_DIR/logs/err.log -a -s $NODEPROXY_DIR/nodeproxy.js 446 | EOLENVSETUP 447 | echo "Creating the post-receive script and sending it to the EC2 server..." 448 | cat > tmp-post-receive < /dev/null 463 | 464 | cd $TMP_APP_DIR 465 | 466 | # Create the node bundle using the meteor/meteorite bundle command 467 | echo "Creating node bundle on the EC2 server..." 468 | # remove local directory if present to avoid potential permission issues 469 | if [ -d "$TMP_APP_DIR/.meteor/local" ]; then 470 | sudo rm -r .meteor/local 471 | fi 472 | # bundle 473 | (unset GIT_DIR; mrt install) 474 | # Why unset? https://github.com/oortcloud/meteorite/pull/165 475 | 476 | # Use NVM to install and use correct version of node 477 | # Do this before bundle command so that npm updates work 478 | echo "Installing and using correct NodeJS version..." 479 | nvm install $NODE_VERSION && nvm use $NODE_VERSION && (sudo ln -sf ~/.nvm/v$NODE_VERSION/bin/node /usr/bin/node; sudo ln -sf ~/.nvm/v$NODE_VERSION/bin/node /usr/local/bin/node) 480 | 481 | echo "Bundling..." 482 | meteor bundle --directory "$BUNDLE_DIR" 483 | 484 | if [ ! -d "$BUNDLE_DIR" ]; then 485 | echo "Meteor bundle command failed!" 486 | sudo rm -rf $TMP_APP_DIR 487 | exit 1 488 | fi 489 | 490 | # Reinstall fibers 491 | # (http://stackoverflow.com/questions/13327088/meteor-bundle-fails-because-fibers-node-is-missing) 492 | #echo "Reinstalling fibers in the node bundle on the EC2 server..." 493 | #if [ -d "$BUNDLE_DIR/programs/server" ]; then 494 | # cd $BUNDLE_DIR/programs/server 495 | # sudo rm -rf node_modules/fibers 496 | # npm install fibers@1.0.1 &> /dev/null 497 | #fi 498 | 499 | # Try to stop the node app using forever, in case it's already running 500 | sudo forever stop $WWW_APP_DIR/main.js &> /dev/null 501 | 502 | # Remove www app directory if it exists 503 | if [ -d "$WWW_APP_DIR" ]; then 504 | sudo rm -rf $WWW_APP_DIR 505 | fi 506 | 507 | # Create www app directory 508 | mkdir -p $WWW_APP_DIR 509 | 510 | # Copy the extracted and tweaked node application to the WWW_APP_DIR 511 | cp -R $BUNDLE_DIR/* $WWW_APP_DIR 512 | 513 | # Clean up any directories that we created 514 | if [ -d "$TMP_APP_DIR" ]; then 515 | sudo rm -rf $TMP_APP_DIR 516 | fi 517 | 518 | cd $WWW_APP_DIR 519 | 520 | # Start the node app using forever 521 | echo "Starting the $1 environment of $APP_NAME on the EC2 server..." 522 | export PORT=$PORT ROOT_URL=$ROOT_URL${MONGO_URL_SETTER}${MAIL_URL_SETTER}${SETTINGS_SETTER} 523 | sudo -E forever start -l $LOG_DIR/forever.log -o $LOG_DIR/out.log -e $LOG_DIR/err.log -a -s $WWW_APP_DIR/main.js &> /dev/null 524 | ENDCAT 525 | # Secure copy the post-receive script we just created, and then delete it 526 | scp $SSH_OPT tmp-post-receive $SSH_HOST:$GIT_APP_DIR/hooks/post-receive &> /dev/null 527 | rm tmp-post-receive &> /dev/null 528 | 529 | echo "Creating the restart script and sending it to the EC2 server..." 530 | touch tmp-restartapp 531 | cat > tmp-restartapp < /dev/null 542 | 543 | # Start the node app using forever 544 | export PORT=$PORT ROOT_URL=$ROOT_URL${MONGO_URL_SETTER}${MAIL_URL_SETTER}${SETTINGS_SETTER} 545 | sudo -E forever start -l $LOG_DIR/forever.log -o $LOG_DIR/out.log -e $LOG_DIR/err.log -a -s $WWW_APP_DIR/main.js &> /dev/null 546 | ENDCAT5 547 | # Secure copy the restartapp script we just created 548 | scp $SSH_OPT tmp-restartapp $SSH_HOST:$APP_DIR/restartapp &> /dev/null 549 | # Then make it executable 550 | ssh -t $SSH_OPT $SSH_HOST < /dev/null 552 | ENDCAT6 553 | # Then delete the local file 554 | rm tmp-restartapp &> /dev/null 555 | 556 | # Secure copy the settings file 557 | if [ -r "$SETTINGS_FILE" ]; then 558 | echo "Copying environment settings to the EC2 server..." 559 | scp $SSH_OPT $SETTINGS_FILE $SSH_HOST:$APP_DIR/settings.json &> /dev/null 560 | fi 561 | 562 | echo "Defining this environment as a local git remote..." 563 | # Make sure SSH knows about the EC2 key file for pushing 564 | ssh-add $EC2_PEM_FILE &> /dev/null 565 | # Set up the environment remote 566 | git remote rm $1 &> /dev/null 567 | git remote add $1 ssh://$SSH_HOST$GIT_APP_DIR 568 | echo 569 | echo "Done! Enter the following command now and whenever you have committed changes you want to deploy to the $1 environment:" 570 | echo " git push $1 master" 571 | echo 572 | --------------------------------------------------------------------------------