• Stars
    star
    788
  • Rank 55,735 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Zero downtime deployment for your Node.js server using builtin cluster API

naught

Build Status

Features:

  • Zero downtime code deployment
  • Resuscitation - when a worker dies it is restarted
  • Redirect worker stdout and stderr to rotating gzipped log files
  • Runs as daemon, providing ability to start and stop
  • Clustering - take advantage of multiple CPU cores
  • Properly handles SIGTERM and SIGHUP for integration with service wrappers
  • Ability to gracefully handle uncaught exceptions
  • Supports POSIX operating systems (does not support Windows)

Usage:

To use naught, your node.js server has 2 requirements.

  1. Once the server is fully booted and is readily accepting connections,

    process.send('online');

    Usually this is done in the listening event for a node server, for example:

    server = http.createServer(...);
    server.listen(80, function () {
      if (process.send) process.send('online');
    });
  2. Listen to the shutdown message and shutdown gracefully. This message is emitted after there is already a newer instance of your server online and taking care of business:

    process.on('message', function(message) {
      if (message === 'shutdown') {
        performCleanup();
        process.exit(0);
      }
    });

    If your server has no long-lived connections, you may skip this step. However, note that most node.js apps do have long lived connections. In fact, by default, the connection: keep-alive header is sent with every request.

    When you receive the shutdown message, either close all open connections or call process.exit().

Gracefully Handling Exceptions

Another way you can use naught is to gracefully handle exceptions that would normally cause errors for users other than the one that triggered the exception.

It is common practice to allow an uncaught exception to crash the Node.js process. In the case of a web server, that forcefully ends the execution of all other connections, resulting in more than a single user getting an error.

Using naught a worker can use the 'offline' message to announce that it is dying. At this point, naught prevents it from accepting new connections and spawns a replacement worker, allowing the dying worker to finish up with its current connections and do any cleanup necessary before finally perishing.

To take advantage of this, you need a way of catching the uncaught exceptions that cause crashes. There are two ways:

The documentation says to use Domains, so use that unless you have a better reason.

Authbind

If you want to deploy on a restricted port such as 80 or 443 without sudo, try authbind.

Note that there are 3 layers of process spawning between the naught CLI and your server. So you'll want to use the --deep option with authbind.

Using a service wrapper

It may make sense to use naught with other process monitoring software. For this reason, naught supports listening to SIGTERM to do a stop operation, and SIGHUP to do a deploy operation. You may also run in the foregroun with --daemon-mode false.

When you run with --daemon-mode true (the default), the process tree looks like this:

  • CLI process, spawns the following (detached) and then exits:
    • daemon process, listens for SIGTERM/SIGHUP, spawns the following and stays running:
      • cluster master process, spawns the following and stays running:
        • worker 1
        • worker 2
        • etc

When you run with --daemon-mode false, the process tree looks like this:

  • CLI process, listens for SIGTERM/SIGHUP, spawns the following and stays running:
    • cluster master process, spawns the following and stays running:
      • worker 1
      • worker 2
      • etc

CLI

naught start [options] server.js [script-options]

    Starts server.js as a daemon passing script-options as command
    line arguments.

    Each worker's stdout and stderr are redirected to a log files
    specified by the `stdout` and `stderr` parameters. When a log file
    becomes larger than `max-log-size`, the log file is renamed using the
    current date and time, and a new log file is opened.

    With naught, you can use `console.log` and friends. Because naught
    pipes the output into a log file, node.js treats stdout and stderr
    as asynchronous streams.

    If you don't want a particular log, use `/dev/null` for the path. Naught
    special cases this filename and disables that log altogether.

    When running in `daemon-mode` `false`, naught will start the master
    process and then block. It listens to SIGHUP for restarting and SIGTERM
    for stopping. In this situation you may use `-` for `stderr` and/or
    `stdout` which will redirect the respective streams to naught's output
    streams instead of a log file.

    Creates an `ipc-file` which naught uses to communicate with your
    server once it has started.

    Available options and their defaults:

    --worker-count 1
    --ipc-file naught.ipc
    --pid-file naught.pid
    --log naught.log
    --stdout stdout.log
    --stderr stderr.log
    --max-log-size 10485760
    --cwd .
    --daemon-mode true
    --remove-old-ipc false
    --node-args ''


naught stop [options] [ipc-file]

    Stops the running server which created `ipc-file`.
    Uses `naught.ipc` by default.

    This sends the 'shutdown' message to all the workers and waits for
    them to exit gracefully.

    If you specify a timeout, naught will forcefully kill your workers
    if they do not shut down gracefully within the timeout.

    Available options and their defaults:

        --timeout none
        --pid-file naught.pid


naught status [ipc-file]

    Displays whether a server is running or not.
    Uses `naught.ipc` by default.


naught deploy [options] [ipc-file]

    Replaces workers with new workers using new code and optionally
    the environment variables from this command.

    Naught spawns all the new workers and waits for them to all become
    online before killing a single old worker. This guarantees zero
    downtime if any of the new workers fail and provides the ability to
    cleanly abort the deployment if it hangs.

    A hanging deploy happens when a new worker fails to emit the 'online'
    message, or when an old worker fails to shutdown upon receiving the
    'shutdown' message. A keyboard interrupt will cause a deploy-abort,
    cleanly and with zero downtime.

    If `timeout` is specified, naught will automatically abort the deploy
    if it does not finish within those seconds.

    If `override-env` is true, the environment varibables that are set with
    this command are used to override the original environment variables
    used with the `start` command. If any variables are missing, the
    original values are left intact.

    `worker-count` can be used to change the number of workers running. A
    value of `0` means to keep the same number of workers.
    A value of 'auto', will set value as per the number of available CPUs.

    `cwd` can be used to change the cwd directory of the master process.
    This allows you to release in different directories. Unfortunately,
    this option doesn't update the script location. For example, if you
    start naught `naught start --cwd /release/1 server.js` and deploy
    `naught deploy --cwd /release/2` the script file will not change from
    '/release/1/server.js' to '/release/2/server.js'. You have to create
    a symlink and pass the full symlink path to naught start
    '/current/server.js'. After creating the symlink naught starts the
    correct script, but the cwd is still old and require loads files from
    from the old directory. The cwd option allows you to update the cwd
    to the new directory. It defaults to naught's cwd.

    Uses `naught.ipc` by default.

    Available options and their defaults:

        --worker-count 0
        --override-env true
        --timeout none
        --cwd .


naught deploy-abort [ipc-file]

    Aborts a hanging deploy. A hanging deploy happens when a new worker
    fails to emit the 'online' message, or when an old worker fails
    to shutdown upon receiving the 'shutdown' message.

    When deploying, a keyboard interrupt will cause a deploy-abort,
    so the times you actually have to run this command will be few and
    far between.

    Uses `naught.ipc` by default.


naught version

    Prints the version of naught and exits.


naught help [cmd]

    Displays help for cmd.

More Repositories

1

groovebasin

Music player server with a web-based user interface.
JavaScript
1,851
star
2

libsoundio

C library for cross-platform real-time audio input and output
C
1,847
star
3

node-s3-client

high level amazon s3 client for node.js
JavaScript
1,004
star
4

poop

Performance Optimizer Observation Platform
Zig
712
star
5

jamulator

(unmaintained) recompiling NES roms into native executables
Go
388
star
6

tetris

A simple tetris clone written in zig programming language.
Zig
345
star
7

libgroove

streaming audio processing library
C
286
star
8

node-diacritics

remove diacritics from strings ("ascii folding") - Node.js module
JavaScript
259
star
9

waveform

simultaneously transcode and generate visuals for an audio file
C
251
star
10

HellOS

"hello world" x86 kernel example
Zig
235
star
11

clashos

multiplayer arcade game for bare metal Raspberry Pi 3 B+
Zig
206
star
12

genesis

Genesis Digital Audio Workstation
C++
176
star
13

chem

2d canvas-based rapid prototyping game engine
JavaScript
176
star
14

swig-email-templates

Node.js module for rendering emails with swig templates and email-friendly inline CSS using boost.
JavaScript
162
star
15

node-groove

bindings to libgroove - music player backend library
C++
155
star
16

node-mv

Like `fs.rename`, but works across devices, and works with directories. Think of the unix utility `mv`.
JavaScript
155
star
17

ffmpeg

ffmpeg with the build system replaced by zig
C
113
star
18

zig-window

window client library
C++
106
star
19

node-waveform

simultaneously transcode audio and generate visuals - Node.js module
C
99
star
20

node-s3-cli

command line utility to go along with node s3 module
JavaScript
97
star
21

malcheck

Test your code with malcheck to make sure it handles out of memory conditions correctly.
C
95
star
22

mpd.js

Connect to a music player daemon server, send commands, emit events.
JavaScript
89
star
23

zig-wasi

Minimal WASI interpreter
C
87
star
24

zasm

multi-target assembler and disassembler
Zig
87
star
25

PyDaw

python library to mess with Digital Audio Workstations. FL Studio project files (.flp) supported.
C++
87
star
26

sdl-zig-demo

SDL2 hello world in zig
Zig
86
star
27

zig-vulkan-triangle

simple triangle displayed using vulkan, glfw, and zig
Zig
81
star
28

node-flp

FL Studio project file parser for node.js
JavaScript
72
star
29

node-tmx-parser

node.js module to parse and load tiled map editor maps (see mapeditor.org)
JavaScript
71
star
30

node-astar

Generic A* algorithm for node.js
JavaScript
67
star
31

node-sox

(unmaintained) node.js interface to the sox audio utility
JavaScript
61
star
32

mcserve

wraps minecraft server and gives you a web interface
JavaScript
54
star
33

zig-async-demo

Comparing concurrent code example programs between other languages and Zig
Zig
53
star
34

zig-general-purpose-allocator

work-in-progress general purpose allocator intended to be eventually merged into Zig standard library. live streamed development
Zig
45
star
35

StaticHttpFileServer

Zig module for serving a directory of files from memory via HTTP
Zig
44
star
36

autodoc

Zig Documentation Generator
Zig
44
star
37

node-perlin-noise

perlin noise generator for node.js
JavaScript
33
star
38

liblaxjson

C library for parsing JSON config files
C
32
star
39

lua-in-the-browser

using zig to build lua for webassembly
C
32
star
40

node-fd-slicer

safely create multiple ReadStream or WriteStream objects from the same file descriptor
JavaScript
30
star
41

flag2struct

simple CLI tool for converting zig source code using flags-style declarations to packed structs
Zig
28
star
42

connect-sse

connect middleware for server sent events (EventSource)
JavaScript
27
star
43

rucksack

texture packer and resource bundler
C
27
star
44

mime

zig package for mapping extensions to mime types
Zig
26
star
45

PyWaveform

Python library to create an image of a song's waveform
C
26
star
46

zig-stage1

Exploring replacing Zig's stage1 compiler with pure C code that outputs pure C code
C
25
star
47

libavfilter-example

small example of using libavfilter to filter audio
C
22
star
48

xml

Tokenize XML
Zig
22
star
49

node-plan

(unmaintained, deprecated, abandoned) Execute a complicated dependency graph of tasks with smooth progress events.
JavaScript
20
star
50

connect-static

static file server middleware for connect. loads files once at startup and saves gzipped versions in memory
JavaScript
19
star
51

dotfiles

linux yo
Nix
18
star
52

pyedsdk

Python library to control cameras via EDSDK
C
18
star
53

node-pend

dead-simple optimistic async helper in javascript
JavaScript
16
star
54

groove-rs

rust bindings to libgroove - streaming audio processing library
Rust
15
star
55

purgatory

escape from the circles of hell - 7 hour game jam
JavaScript
15
star
56

evo

specification, reference implementation, and examples of Evo, the programming language made for being the DNA of genetic algorithms
Zig
15
star
57

mediablast

(unmaintained, deprecated, abandoned) open source media processing server
JavaScript
14
star
58

browserify-lite

browserify, minus some of the advanced features and heavy dependencies
JavaScript
14
star
59

pillagers

Real time strategy game with space physics
JavaScript
12
star
60

hackerrank

my solutions to hackerrank puzzles
Go
11
star
61

connect-nocache

connect middleware to insert no cache headers
JavaScript
11
star
62

andrewkelley.me

my personal site
HTML
11
star
63

SIMD-test

exploring SIMD optimization
C
10
star
64

truthfinder

TruthFinder.org website
Python
10
star
65

mc-bot-server

(unmaintained) server that spins up minecraft bots
JavaScript
9
star
66

pulseaudio

pulseaudio with the build system replaced by zig
C
9
star
67

zig-mandelbrot-gl

mandelbrot set in zig
Zig
9
star
68

node-yawl

yet another websockets library for Node.js
JavaScript
8
star
69

clashproto

prototyping the game for andrewrk/clashos
Zig
8
star
70

planet-evo

evolution simulation software
C++
8
star
71

advent-of-code

https://adventofcode.com
Zig
8
star
72

node-music-library-index

node module to build a searchable javascript object model given track metadata objects
JavaScript
7
star
73

github-popularity-contest

see who has the most collective stars
JavaScript
7
star
74

node-human-size

tiny node.js module to get human readable file size from byte count
JavaScript
7
star
75

libmp3lame

libmp3lame with the build system replaced by zig
C
7
star
76

node-stream-counter

node.js module to keep track of how many bytes have been written to a stream
JavaScript
7
star
77

mpd

a fork of mpd to add library management, better search, and a sophisticated dynamic playlist
C
7
star
78

boost

Inline CSS into your HTML source
JavaScript
6
star
79

Secure-WordVault

(unmaintained, deprecated, abandoned) Enables you to store sensitive information in a portable manner
C++
6
star
80

TrenchBowl

simple music player UI to demonstrate libgroove
C++
6
star
81

node-spritesheet

node.js module: given a list of image files, create a spritesheet using cairo
JavaScript
6
star
82

chem-cli

html5 canvas game engine optimized for rapid development - command line interface
JavaScript
5
star
83

face-the-music

indie speed run game jam
JavaScript
5
star
84

dominion

Node.js module and command line program to play Dominion, the card game by Donald X. Vaccarino.
JavaScript
5
star
85

ruff

little tool to help my dad quickly find info in a .csv file
C++
5
star
86

gbremote

Groove Basin remote control command line app and Node.js module
JavaScript
5
star
87

archerbot

mineflayer bot that engages you in a gentlemanly duel
JavaScript
5
star
88

holocaust

html5 video game - rebuild society after a nuclear holocaust ravages the world
JavaScript
4
star
89

planetarius

Ludum Dare 30 Entry. networked multiplayer arcade shooter
JavaScript
4
star
90

Camlift-Controller

Controls a Canon camera and operates a motorized lift
Visual Basic
4
star
91

swig-dummy-context

given a swig template, create a dummy context which is useful for template composing tools
JavaScript
4
star
92

node-passthrough-truncate

truncate the last N bytes of a stream - Node.js module
JavaScript
3
star
93

scrabble

Scrabble solving AI
3
star
94

spacefight

vaporware 3D space-dogfighting simulator game
C++
3
star
95

math3d-rs

computer-graphics matrix calculations for dummies like me
Rust
3
star
96

lemming-js

PyWeek #12 entry ported to JavaScript with chem
JavaScript
3
star
97

pypowerusb

Python library to control a PowerUSB
C
3
star
98

opengl-multi-window-test

see if multiple windows in opengl causes a framerate issue
C
3
star
99

disinfecticide

A game about controlling a disease outbreak.
JavaScript
2
star
100

socketio-ssl-test

test whether we can use socket.io with xhr requests securely on an insecure page
JavaScript
2
star