Getting your Node.js app production ready
## What's this node thing good for?
* translation layers
* websockets on top of heavy services
* microservice architectures
## How does it work?
* event loop
* all asynchronous
* no concurent memory access
* 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
const express = require('express')
const app = express()
### Running in production
* `node app.js` - forget it
* `forever`, `cluster` - no, thanks
* PM2! http://pm2.keymetrics.io/
* Containers / Docker / Now
* Serverless - AWS Lambda etc.
> 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.
but with all features of a process manager extracted outside and great infrastructure building/scaling tools.
* You only write the logic,
* Infrastructure, http layer and scaling is already provided
* You pay for number of function runs, not servers waiting for traffic
> Mindblowing, but not applicable for everyone
### 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
## Some good practices
for writing the app
* 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.)
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](https://github.com/naugtur/strongly-typed) can be enough. And are easy to add to an existing app
* You can go all in and use Typescript or facebook's Flow.
### Feature toggles
Good for keeping your master branch deployable.
* Make them easy to find in code
* Always remove them after no longer needed
* Don't put tons of `if`s in code, duplicate a file and `require` depending on toggle value
## Manage dependencies
* When in doubt, `npm shrinkwrap`
* Don't install unmaintained code if it saves you 3 lines
* Node Security Project and requireSafe
## Getting dependencies to production
* npm install with shrinkwrap file? - not bulletproof
* `yarn` - a more precise npm client
* `secure-dependencies` for bundling dependencies as build artifacts
* bundle the whole app - use docker
## secure dependencies
*never run npm install in production again!*
npm install secure-dependencies --save-dev
`npm run bundle` --> myapp-1.0.0.tgz
# And now we're in production
* Use log levels
* Enable changing log level without restarting the app. Most bugs stop reproducing after you restart.
* IF you expect more than one user, generate a random ID for each HTTP request and add it to all logs it generates.
* Logs should not contain user credentials etc.
* Build a sanitizer that hashes sensitive data
[03-12_00:50:14.181] TRACE  authorization: 'Bearer
## 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
console.log('BLOCKED FOR %s ms', ms | 0);
* Finding them is harder. My little experiment: [promise-blocked](https://github.com/naugtur/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](https://github.com/felixge/node-memory-leak-tutorial), but very old
* In production - take a heapdump and then another, compare
It's an old topic, noone is getting into a conference lineup with it, so no new content.
I have some fresh content about it, for training. (private use permitted)
## maintenance endpoint
Create a separate http server listening on `localhost:1337` that will handle:
* Switching log level without restart
* Generating a heapdump
* Healthcheck endpoint (can also be public)
* 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
* Much more security tips
* Safe, non leaking, object caches
* No-downtime redeploys
## Advanced debugging in production
Recent [talk](http://techblog.netflix.com/2015/12/debugging-nodejs-in-production.html) from Netflix is a must.
* Flame graphs [2014 at Netflix](http://techblog.netflix.com/2014/11/nodejs-in-flames.html)
* Joyent had flame graphs [long ago](http://www.joyent.com/blog/walmart-node-js-memory-leak)
* Postmortem debugging from a core dump with `mdb` on smartos
* [Post Mortem Diagnostics Working Group](https://github.com/nodejs/post-mortem)
@naugtur, Code Europe 2016
Follow me for workshops on this
Subscribe to my newsletter http://naugtur.pl/news 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