5 minutes to Dockerizing your Node.js Application

Who am I?

  • Josh Finnie (@joshfinnie)
  • Senior Software Maven @ TrackMaven
  • NodeDC co-Organizer
  • Lover of JavaScript
  • Coder of Python (and CoffeeScript)
  • Docker Aficionado 

Background

  • TrackMaven, we're a python shop
  • But, we use Angular.js (and CoffeeScript)
  • Also, breaking our monolith into microservices

The Perfect Storm

Allows for Right Tool for the Right Job (The Dream!)

  • Microservices can be written in languages that make sense for the task at hand.
  • We are not limited to a Pythonic Monolith
  • We moved to Service ownership, so you write it, you own it.

Hello 
docker-node-express-skeleton

docker-node-express-skeleton

A skeleton project that will get you up and running with Node, Express, & ES6 in Docker.

 

Caveat: This is very opinionated, there are other ways to do this. But, I think this is a best practice.

Tools Used

FROM node:4.4.0
MAINTAINER Josh Finnie <josh.finnie@trackmaven.com>

RUN npm install -g pm2@1.0.2 babel-core@6.7.2

ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /code && cp -a /tmp/node_modules /code

ADD .babelrc /code/.babelrc
ADD app /code/app

WORKDIR /code/

CMD ["pm2", "start", "/code/app/app.json", "--no-daemon"]

Docker

web:
  build: .
  ports:
    - "1234:1234"
  volumes:
    - ./app:/code/app
  env_file:
    - .env

Docker Compose

'use strict';

import http from 'http';

import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
import express from 'express';

import api from './api';

console.log("in server/index.js");

let app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());

app.use('/api', api());

app.server = http.createServer(app);
app.server.listen(process.env.PORT || 1234);

console.log(`Started on port ${app.server.address().port}.`);

export default app;

Express

{
    "apps": [
        {
            "name": "server",
            "script": "/code/app/index.js",
            "watch": ["./"],
            "ignore_watch" : ["node_modules"],
            "watch_options": {
                "usePolling": true
            }
        }
    ]
}

PM2

require('babel-core/register');
require('./server');

Babel.js


'use strict';

import { Router } from 'express';

export default function() {
    let api = Router();

    api.get('/', (req, res) => {
        res.json({
            version: '1.0'
        });
    });

    return api;
}

ES2015

The Choices

  • Docker - Containerization is so cool.
  • Docker Compose - Makes Docker easy, trust me!
  • Node.js - Streaming Architecture's where it's at!
  • Express.js - Ehh
  • Babel.js & ES2015 - The Future is NOW
  • PM2 - Nodemon sucks, uses bad practices and should feel bad!

Diatribe about Choices...

Rant about
Choices...

Questions?

Thanks!

  • Josh Finnie (@joshfinnie)
  • Senior Software Maven @ TrackMaven
  • NodeDC co-Organizer
  • Lover of JavaScript
  • Coder of Python (and CoffeeScript)
  • Docker Aficionado