How do you deploy a Node.js app without downtime?
I had asked this question in the upcoming Devmag's private beta website and got some really nice answers. So, I am requesting @sportebois, @fibric and @KapuzenSohn to add their answers here so that everyone here can take advantage of it.
3.4K+ developers have started their personal blogs on Hashnode in the last one month.
Write in Markdown · Publish articles on custom domain · Gain readership on day zero · Automatic GitHub backup and more
Node.js developer. Experimenting with bleeding-edge tech. Irregularly DJ. Hobby drone pilot. Amateur photographer.
On Linux, we are using
- on initial deploy publish into target directory <timestamp>, save timestamp into local file
- on update deploy publish into target directory with newer <timestamp>, save timestamp also into local file
- programmatically adjust NDM to shut down PID of the process with the older timestamp (taken from file) then start the process from the folder with the newer timestamp (taken from timestamp file).
Timestamps are taken from the local file and not from existing folders. Allows rollback, fast version switching, etc.
It's also possible with PM2 too, but PM2 has its own dependencies on a specific Node version. That's why we skip PM2 and use NDM.
It's still not zero-down-time like it's done on Erlang/Elixir, but it's quite close too.
Another alternative I've started yesterday is by using Nginx & nginScript. With the current approach, it's still possible to lose some requests (chances are quite low because stopping the process, starting a new one is done in less than ~20ms). Erlang routes requests from one PID to another, losing 0 requests - always. This is what I am trying to achieve now with Nginx & nginScript. Route requests based the on the content of the timestamp file. Currently, I'm clashing with base router rules config and nginScript code. But when I've tamed the beast, then we shouldn't lose any request.
For zero downtime deployment I use on my server dokku.
It has many features and is based on docker. You just install it on a server and then you add a git remote connection and then you just push and dokku makes all the magic ;)
When you have for example a Express server with a route like
/myurl/test then you can create a
CHECK with contains this route and during the startup dokku checks if this route is available.
It has more features just check it out :)
Hello Not used for NodeJs, but as long as it's within a Docker container, the idea will be the same. Amazon's ECS will do it for you, as long as you're running more than one instance. - update your task definition to target your new image - downscale the desired tasks from n to n-1 - restore your desired tasks to it's original value. The new slot will be started with the new version. - once started, the instance(s) running the old version will be stopped by ECS and restarted with the new version, one by one.
(plug it with wercker, and you have your ci/cd chain up and running)