Skip to content

Instantly share code, notes, and snippets.

@learncodeacademy
Last active January 7, 2024 11:58
Show Gist options
  • Save learncodeacademy/35045e64d2bbe6eb14f9 to your computer and use it in GitHub Desktop.
Save learncodeacademy/35045e64d2bbe6eb14f9 to your computer and use it in GitHub Desktop.
Deploy Node.js Apps with Flightplan

##Setup your server (this would ideally be done with automated provisioning)

  • add a deploy user with password-less ssh see this gist
  • install forever npm install -g forever

##Install flightplan

  • npm install -g flightplan
  • in your project folder npm install flightplan --save-dev
  • create a flightplan.js file
var plan = require('flightplan');

var appName = 'node-app';
var username = 'deploy';
var startFile = 'bin/www';

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

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

plan.target('production', [
  {
    host: '104.131.93.215',
    username: username,
    agent: process.env.SSH_AUTH_SOCK
  },
//add in another server if you have more than one
// {
//   host: '104.131.93.216',
//   username: username,
//   agent: process.env.SSH_AUTH_SOCK
// }
]);

// run commands on localhost
plan.local(function(local) {
  // uncomment these if you need to run a build on your machine first
  // local.log('Run build');
  // local.exec('gulp build');

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

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

  remote.log('Install dependencies');
  remote.sudo('npm --production --prefix ~/' + tmpDir + ' install ~/' + tmpDir, {user: username});

  remote.log('Reload application');
  remote.sudo('ln -snf ~/' + tmpDir + ' ~/'+appName, {user: username});
  remote.exec('forever stop ~/'+appName+'/'+startFile, {failsafe: true});
  remote.exec('forever start ~/'+appName+'/'+startFile);
});

##Deploy!

  • fly staging or fly production

##Take it to the next level Run your node app as a system service so it runs after server reboots

@hintonbradley
Copy link

Hey! Good tutorial - thanks for making this.
All goes well until the very last step. When I attempt to push to production (fly production), I get an the following error:

✈ Running default:production
✈ Executing local task
localhost Copy files to remote hosts
localhost $ git ls-files
localhost ● ok
● Empty file list passed to transfer()

Anyone have any ideas? FYI: I'm running on a mac.

@gbrits
Copy link

gbrits commented May 26, 2019

You have to perform a git add . for the first git ls-files to have tracked files. So first git add . then fly production

@gbrits
Copy link

gbrits commented May 26, 2019

For anyone running into authentication issues, try explicitly declaring your privateKey: 'path/to/the/.ssh/id_rsa', in your staging/production configs.

@ronikiko
Copy link

ronikiko commented Jun 2, 2019

hello all
i get this error why?
localhost ● ok
✈ Local task finished after 16 s
✈ Connecting to 'XXX.XXX.XX.XX'
● Error connecting to 'XXX.XXX.XXX.XX': All configured authentication methods failed

@SumitGA
Copy link

SumitGA commented Oct 31, 2019

I was working on my Vagrant Box and got these issues

localhost ● ok
✈ Local task finished after 16 s
✈ Connecting to 'XXX.XXX.XX.XX'
● Error connecting to 'XXX.XXX.XXX.XX': All configured authentication methods failed

The issue was with ssh connection, so I went up to my vagrant config file and added
config.ssh.forward_agent = true

Then I was able to run fly production and deploy to my vagrant box. Also, make sure to check your production server has node and forever installed correctly or else it will not work.

@kennylugo
Copy link

kennylugo commented Nov 17, 2019

You have to perform a git add . for the first git ls-files to have tracked files. So first git add . then fly production

This worked for me, thanks! Error I was having before was: localhost > rsync: link_stat failed: No such file or directory (2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment