naught icon indicating copy to clipboard operation
naught copied to clipboard

Provide new 'cwd' option during deploy

Open JoshuaGross opened this issue 11 years ago • 30 comments

I don't really understand how to use Naught in a robust way for new deploys. My current deploy script has a git post-receive hook that brings the old server down and a new server up; if the new server fails, it will rollback and bring the old server back up. One thing I'd like to do with Naught is provide new CWDs in a deploy and then periodically check the health of the new deploy and switch back to the old CWD if necessary. What I'll do for now is symlink a directory and point Naught to that, but this seems strange.

JoshuaGross avatar Mar 05 '13 16:03 JoshuaGross

Your request makes sense; however I think we may be limited by node's cluster API.

andrewrk avatar Mar 05 '13 17:03 andrewrk

Ahh, I didn't realize that. Makes sense. Do you manage production deploys in a similar way to me / do you have any suggestions for how to do this elegantly?

JoshuaGross avatar Mar 05 '13 19:03 JoshuaGross

We currently use rodent to do production deploys. It may not be generic enough for your use case, but here's what a deploy looks like:

  • developer pushes the code to a remote branch (usually master)
  • developer executes the deploy command
  • on each production target
    • git fetch
    • git checkout origin/(deploy-branch)
    • npm install
    • ./node_modules/.bin/naught deploy

So there are no backup folders with previous releases to roll back to. However, deploys are very fast, usually taking about 5 seconds. So if you want to roll back to a previous commit, you can deploy that previous commit and the previous commit will be live in 5 seconds.

andrewrk avatar Mar 05 '13 20:03 andrewrk

I think I like that better than the current system, which takes much longer than 5s to deploy and doesn't really use the power of Git. Thanks - this is informative!

Joshua Gross Christian / SpanDeX, Inc. / BA of Computer Science, UW-Madison 2013 http://www.joshisgross.com / http://www.spandex.io

On 5 March 2013 14:07, Andrew Kelley [email protected] wrote:

We currently use rodent https://github.com/indabamusic/rodent to do production deploys. It may not be generic enough for your use case, but here's what a deploy looks like:

  • developer pushes the code to a remote branch (usually master)
  • developer executes the deploy command
  • on each production target
    • git fetch
    • git checkout origin/(deploy-branch)
    • npm install
    • ./node_modules/.bin/naught deploy

So there are no backup folders with previous releases to roll back to. However, deploys are very fast, usually taking about 5 seconds. So if you want to roll back to a previous commit, you can deploy that previous commit and the previous commit will be live in 5 seconds.

— Reply to this email directly or view it on GitHubhttps://github.com/indabamusic/naught/issues/25#issuecomment-14462133 .

JoshuaGross avatar Mar 06 '13 00:03 JoshuaGross

We perform deploys the capistrano / chef way, so the deploy process creates a /release/<version> directory and then creates a symlink from /current to the latest deployed version dir. So we face the problem of the cwd in the deploy command.

A quick workaround that I've seen here: http://clarkdave.net/2013/02/node-js-and-cluster-cwd-dirname-shenanigans/ would be to chdir inside the main script of the app using the __dirname variable:

if (__dirname !== process.cwd()) {
  process.chdir(__dirname);
}

Even this does not involve any change in naught, I think it would be cleaner if there was a way to change the cwd during a naught deploy.

iuriaranda avatar Feb 20 '14 11:02 iuriaranda

Feel free to make a PR. This feature can easily lead to subtle problems - I think we want an automated test or 2 for this feature.

andrewrk avatar Feb 20 '14 17:02 andrewrk

This is now implemented and released in 1.2.0 thanks to dmcaulay

andrewrk avatar Mar 18 '14 18:03 andrewrk

I have a node.js app (express) in folder1. I start the server using "naught start app.js". I now would like to deploy the updated version located in folder2. I run (from folder1) "naught deploy --cwd ../folder2".

I get the following result:

SpawnNew. booting: 1, online: 1, dying: 0, new_online: 0 NewOnline. booting: 0, online: 1, dying: 0, new_online: 1 ShutdownOld. booting: 0, online: 0, dying: 1, new_online: 1 OldExit. booting: 0, online: 0, dying: 0, new_online: 1 done

The server is still up, but folder1 is still deployed, instead of folder2. I would like to make the switch from folder1 to folder2 with zero downtime. Any suggestions?

danshulman avatar Mar 23 '14 18:03 danshulman

cc @dmcaulay

andrewrk avatar Mar 23 '14 19:03 andrewrk

@andrewrk I'll take a look

dmcaulay avatar Mar 23 '14 22:03 dmcaulay

@zenshulman I've updated my fork with a possible fix. I've tested locally, but I want to make sure it works for you before opening a PR. Can you test with my fork? https://github.com/prix-fixe/naught

dmcaulay avatar Mar 23 '14 22:03 dmcaulay

@zenshulman I want to clarify that the cwd option does not change the script location. I'm using a symlink for that.

For example if you run naught deploy --cwd '/release/2' it doesn't change the script file location from '/release/1/server.js' to '/release/2/server.js'. It only changes the cwd directory for the master process. This is needed because the workers inherit the cwd from the master process.

I think we could update the script file, but that would take a little more work. What do you think @andrewrk? Should the cwd option change the script location on deploy?

dmcaulay avatar Mar 24 '14 00:03 dmcaulay

Oh, I thought cwd role is to change the script. Using symlink works, but what's cwd for?

danshulman avatar Mar 24 '14 20:03 danshulman

if cwd exists, it seems like it should work for this use case, right?

andrewrk avatar Mar 24 '14 20:03 andrewrk

For what use case? Switching scripts from different folders?

danshulman avatar Mar 24 '14 20:03 danshulman

Yes. This is your use case, correct?

andrewrk avatar Mar 24 '14 20:03 andrewrk

It is. But using cwd alone with no symlink doesn't change the script.

danshulman avatar Mar 24 '14 20:03 danshulman

Sorry, to be clear, I am arguing in favor of your use case. I am saying that as is it is broken and we should support this use case.

andrewrk avatar Mar 24 '14 20:03 andrewrk

ah, ok great. Yes, I 'm totally in favor of that :)

danshulman avatar Mar 24 '14 20:03 danshulman

i just reviewed the docs and im not sure if that's possible. check it out. http://nodejs.org/api/cluster.html#cluster_cluster_setupmaster_settings

"Only the first call to .setupMaster() has any effect, subsequent calls are ignored"

also cluster.settings http://nodejs.org/api/cluster.html#cluster_cluster_settings

"It is effectively frozen after being set, because .setupMaster() can only be called once."

dmcaulay avatar Mar 24 '14 20:03 dmcaulay

@zenshulman you need to change cwd because it's used when you require files. If it is not updated then require will load the files from the old directory.

dmcaulay avatar Mar 24 '14 20:03 dmcaulay

cool, got it!

danshulman avatar Mar 24 '14 20:03 danshulman

Wait, so how come when I deploy after changing only the symlink ("naught deploy" only, no pwd option), I see changes from the new folder?

danshulman avatar Mar 24 '14 21:03 danshulman

Because cwd defaults to the cwd of the naught script.

dmcaulay avatar Mar 24 '14 21:03 dmcaulay

I looked into it, and sadly I think @dmcaulay is right - we already call process.chdir with the new cwd when you deploy, but it doesn't work for the script.

See https://github.com/joyent/node/issues/3893 and https://github.com/joyent/node/issues/6264

andrewrk avatar Mar 24 '14 21:03 andrewrk

ah ok, so I'll use the symlink method then.

danshulman avatar Mar 24 '14 21:03 danshulman

@andrewrk we should probably update the readme so this is clearer. do you want me to take a stab at it and open a pr?

dmcaulay avatar Mar 24 '14 21:03 dmcaulay

sure, why not

danshulman avatar Mar 24 '14 21:03 danshulman

@dmcaulay yes please. meanwhile I opened the above issue in joyent/node

andrewrk avatar Mar 24 '14 21:03 andrewrk

Great! Started testing this out yesterday and didn't work, then I read through the GitHub issues here, saw it was fixed three hours before, pulled from repo and it started working. :)

I've described how to setup naught with an upstart service wrapper and Git push deployment here in case anyone is interested. All the rest is still WIP though.

freezy avatar May 01 '14 06:05 freezy