Getting your Node.js app production ready

Practical guide

@naugtur, polyconf 2016

## Didn't @Zef just tell us not to use it? * 0.4 - I've never even seen it * 0.10 Walmart Black Friday * 4.0 LTS 6.0 Current stable
## What's this node thing good for? * translation layers * websockets on top of heavy services * middlewares * integrations * microservice architectures
## How does it work? * event loop * all asynchronous * no concurent memory access
## Why write JavaScript? * You all know some of it by now * Still kinda mandatory for web apps * It's everywhere * Decent language if you know what to avoid
### So, you're writing an app ```javascript const express = require('express') const app = express() app.get('/answer/to/:anything',function(req,res){ res.status(200).send('42') }) app.listen(1337) ```
### Running on a server * `node app.js` - forget it * `forever`, `cluster` - no, thanks * PM2! >PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

Process Manager FTW

### Basic monitoring * server resources * is app running * can app be accessed >If your company (like mine) has centralized monitoring already, you're better off leveraging that. >The best monitoring is the one that has someone looking at it
But first ## Some good practices for writing the app
### Stateless * No client information exists in the app between requests * Multiple copies of the app can handle requests from the same user * Stateless = simple horizontal scaling * Redis for shared temporary state (sessions etc.)
![ASYNCHRONOUS](async.jpg) Promises! Did you know asynchronous JSON parsers exist?
### Enforce types sometimes >Dude, you're talking about JS, right? * Some important objects that carry data through your app need to have checks on them. * Tiny tools like [strongly-typed]( can be enough. And are easy to add to an existing app * Major tools like facebook's Flow * You can go all in and use Typescript.
## Manage dependencies * When in doubt, `npm shrinkwrap` * Don't install unmaintained code if it saves you 3 lines * Node Security Project and requireSafe ![nsp check](nsp.png)
# And now we're in production
## Logging IF you expect more than one user, generate a random ID for each HTTP request and add it to all logs it generates. ![info logs](logs.png)
## Use log levels * Fatal, Error are pretty obvious * Warn can be an error you don't mind * Info is for tracking what app does regularly * Debug is for logs that help you understand what's up * Trace should contain enough data to reproduce Enable changing log level without restarting the app. Most bugs stop reproducing after you restart.
## Sanitize * Logs should not contain user credentials etc. * Build a sanitizer that hashes sensitive data ``` [03-12_00:50:14.181] TRACE [75577] authorization: 'Bearer (sha256:bea5d8a8afabfb21b1b8234c23b12ea44f1180c6a96d53c5)' ```
## What to monitor I'm not going to go through features of tools like keymetrics or newRelic
## HTTP request time and status * Watch for 5XX and alert immediately. * Monitor other statuses for popularity. Too many 404s may be a problem too. * Keep statistics on response time separately for every endpoint * Time requests made by the app
## Loop blocks * Use `blocked` to detect ``` blocked(function(ms){ console.log('BLOCKED FOR %s ms', ms | 0); }); ``` * Finding them is harder. For promises, try [promise-blocked]( * Some monitoring tools integrate with node to do that
## Memory increase * Node.js will shutdown when 1.5GB gets allocated * Monitor `process.memoryUsage().rss` * Watch for steady increase in memory use
## Debugging memory leaks * `v8-profiler` in dev/staging * Simple [tutorial]( from 5yr ago * In production - take a heapdump and then another, compare
## maintenance endpoint Create a separate express app listening on `localhost:1337` that will handle: * Switching log level without restart * Generating a heapdump * Healthcheck endpoint * Runing scripts for diagnostics or data migration * Returning basic stats for monitoring (unless you're using tools that integrate directly into node)
## Things I didn't squeeze into the presentation * Getting and using heapdumps * Error handler shared across the app * Feature toggles * Much more security tips * Safe, non leaking, object caches * No-downtime redeploys
## Debugging in production Recent [talk]( from Netflix is a must. * Flame graphs [2014 at Netflix]( * Joyent had flame graphs [long ago]( * Postmortem debugging from a core dump with `mdb` on smartos * [Post Mortem Diagnostics Working Group](

Follow me for workshops on this


Subscribe to my newsletter and get:

  • notifications about events I organize before everyone else (think tickets)
  • access to learning resources I produce
  • no spam, less than 1 email a month on average