l1dzfw
Last Updated: March 23, 2016
·
7.894K
· pstadler
Me japan

Flightplan - deploy like a boss

Updated November 22nd, 2014: code examples compatible with Flightplan >=0.5.0

Flightplan is a node.js library for streamlining application deployment or systems administration tasks, similar to Python's Fabric.

Setup

First we need to install the Flightplan package:

npm install -g flightplan         // system-wide access to the `fly` command.
npm install flightplan --save-dev // install to use in your current project

Then we create a file called flightplan.js:

var plan = require('flightplan');

Deployment targets

Now it's time to set up our deployment targets. In this case we specify targets for staging and production.

// configuration
plan.target('staging', {
  host: 'staging.pstadler.sh',
  username: 'pstadler',
  agent: process.env.SSH_AUTH_SOCK
});

plan.target('production', [
  {
    host: 'www1.pstadler.sh',
    username: 'pstadler',
    agent: process.env.SSH_AUTH_SOCK
  },
  {
    host: 'www2.pstadler.sh',
    username: 'pstadler',
    agent: process.env.SSH_AUTH_SOCK
  }
]);

As you can see, each target consists of one ore more hosts. These hosts will be the target for the command sequences we'll define in the next step.

Flights - sequences of commands

Let's create a local flight to compile our project's assets and distribute its files to the remote host(s):

var tmpDir = 'pstadler-sh-' + new Date().getTime();

// run commands on localhost
plan.local(function(local) {
  // compile assets
  local.log('Run build');
  local.exec('gulp build');

  // confirm deployment to production, as we don't want to do this accidentally
  if(plan.runtime.target === 'production') {
    var input = local.prompt('Ready for deploying to production? [yes]');
    if(input.indexOf('yes') === -1) {
      local.abort('user canceled flight'); // this will stop the flightplan right away.
    }
  }

  // rsync files to all the target's hosts
  local.log('Copy files to remote hosts');
  var filesToCopy = local.exec('git ls-files; find assets -type f', {silent: true});
  local.transfer(filesToCopy, '/tmp/' + tmpDir);
});

If one of the above commands fails (returns a non-zero exit code), the current flight will be aborted and
subsequent commands and flights won't get executed.

If everything went well we want to continue with our deployment on the remote host(s). This can be done
by defining a remote flight.

// run commands on remote hosts
plan.remote(function(remote) {
  remote.log('Move folder to web root');
  remote.sudo('cp -R /tmp/' + tmpDir + ' ~', {user: 'www'});
  remote.rm('-rf /tmp/' + tmpDir);

  remote.log('Install dependencies');
  remote.sudo('npm --production --prefix ~/pstadler-sh install ~/pstadler-sh', {user: 'www'});

  remote.log('Reload application');
  remote.sudo('ln -snf ~/' + tmpDir + ' ~/pstadler-sh', {user: 'www'});
  remote.sudo('pm2 reload pstadler-sh', {user: 'www'}); // pm2 is awesome!
});

Remote flights are executed in parallel on all the targets's remote hosts we defined with target().

If we want to clean up our localhost after the deployment we can do this by defining another local flight:

plan.local(function(local) {
  local.log('Clean up');
  local.exec('gulp clean');
});

// ... and another remote flight, followed by another local flight...
plan.remote(function(remote) { /* ... */ });
plan.local(function(local) { /* ... */ });
// ...and so on.

Executing the flightplan

To deploy our app to the staging environment we run fly staging and once we're ready for production we run fly production, simple as that.

Now check out Flightplan on GitHub, and set up your own flightplan.

Say Thanks
Respond

9 Responses
Add your response

13260
D3b2094f1b3386e660bb737e797f5dcc

Hey Paul,

Nice work. I'm using capistrano now for Node deployments to Linux. What do you see as the advantages of flightplan over cap for Node apps?

Cheers,
Steve

over 1 year ago ·
13261
Me japan

Patrick here.

This depends on your use case. Capistrano is a nice piece of software but it's a little bloated for my taste. If you stumble upon a flightplan.js, you should be able to understand what's going on without consulting a manual first. If you are a developer by day and a sysop by night, then give it a shot.
And of course, Flightplan is a good fit for node.js projects as there's no need to manage another environment.

PS the Java devs at my company wrote a couple of flightplans - fully featured with Hipchat notifications - to deploy their services. Mission complete.

over 1 year ago ·
14083

@pstadler, this is awesome. I was curious, and I was digging through your examples on the repo, but do you have a good method / approach for integrating Flightplan with a git hook callback?

I've tried a few things, but my ops skills are average at best. All I really want to do, for now, is have it exec the fly local on the server (or even simpler, just exec a gulp build, really).

Just curious if you have any suggestions. Thanks for sharing and building this, we're ramping up our deploy and I plan to definitely use the full features in this when we're ready.

over 1 year ago ·
14088
Me japan

Two possible solutions:

  • Install a post-commit hook on the server to trigger either a gulp task or flightplan
  • Use flightplan to deploy directly without using git / hooks

I know that push-based deployment is the cool kid, but that doesn't mean that it always matches your requirements.

over 1 year ago ·
17019
None

Hi. How do you think flight plan compares to stagecoach? Would you recommend one over another for node.js apps.

over 1 year ago ·
17024
Me japan

Flightplan is a tool for executing shell commands on local and remote hosts. What you do with it is entirely up to you. It's excellent for deploying apps, but it can do much more than that. We're using it also to restart applications and for getting metrics like status, memory consumption, running version, and so on. Check this out: https://coderwall.com/p/0andlq

Stagecoach basically provides you an interface to deploy and interact with a specific server setup (i.e. forever + some tooling). It's quite cool, but too strict for my taste.

over 1 year ago ·
17591
None

Just a quickie.
In plan.local(function(local) you're suddenly using transport.prompt() instead of local.prompt().

over 1 year ago ·
17592
Me japan

Fixed, thank you.

over 1 year ago ·
22669
Omid portrait linkedin

Hello!

I need a tool to copy my files from local to server, but also keep some versioning on the server using symlinks. For example, if I make a mistake, I can easily revert back to previous deploy immediately. Would that be easy with flightplan?

over 1 year ago ·