The Twelve-Factor App for Node.js Developers at KharkivJS

The Twelve-Factor App for Node.js Developers at KharkivJS


Nikita Galkin

October 05, 2019


  1. The Twelve-Factor App for Node.js Developers by Nikita Galkin Oct

    5, 2019
  2. What is Quality? 2 Motivation Reduce onboarding time A common

    language with DevOps Engineers Scale-ready app Cloud-ready app Production-ready app Etc-ready app
  3. None
  4. Nikita Galkin Love and Know: ▰ How to make developers

    and business happy ▰ Technical and process debt elimination Believe that: ▰ Any problem must be solved at the right level ▰ Software is easy. People Are Complicated ▰ A problem should be highlighted, an idea should be "sold", a solution should be demonstrated Links: Site GitHub Twitter Facebook

  6. I. Codebase One codebase tracked in revision control, many deploys

  7. What is Quality? 9

  8. None
  9. 11 Scoped packages

  10. What is Quality? 12 Shared code: ▰ Don’t use gitsubmodules,

    use scoped packages ▰ @project/code-style is good first chose Check Code Style and Violence by Anton Nemtsev ▰ On self-hosted repo npm config set @myco:registry ▰ With a self-hosted repo, use add .npmrc to git
  11. II. Dependencies Explicitly declare and isolate dependencies

  12. None
  13. What is Quality? 15 Package.json ▰ avoid npm install -g

    ... ▰ package-lock.json should published in git ▰ node & npm versions fixed ▰ post-install script is a good place for hacking node_modules
  14. What is Quality? 16

  15. FROM node:10.16.3-alpine ENV APP_WORKDIR=/usr/src/app RUN apk update && apk upgrade

    && \ apk add --virtual build-deps git openssh-client py-pip make COPY package.json package-lock.json $APP_WORKDIR WORKDIR $APP_WORKDIR RUN npm install COPY . $APP_WORKDIR RUN npm run build RUN rm -rf tsconfig.json src RUN apk del build-deps RUN npm prune --production CMD ["node", "dist/index.js"]
  16. III. Config Store config in the environment

  17. What is Quality? 19 ▰ Config is not part of

    the artifact ▰ App could be made open source at any moment, without compromising any credentials.
  18. What is Quality? 20 .env ▰ Use .env.example file for

    description ▰ Use .env file for local development ▰ Use environment variables for any other environment ▰ Don’t use default config values in your code ▰ Break your start process if any value missed
  19. # .env.example # Default log level LOG_LEVEL=info # Graceful shutdown

    timeout in milliseconds SHUTDOWN_TIMEOUT=1000 # HTTP Boundary port HTTP_PORT=8000 # Redis connection string REDIS_URI=redis://
  20. require('dotenv-safe').load({ allowEmptyValues: true, path: join(__dirname, '..', '.env'), sample: join(__dirname, '..',

    '.env.example') }); const logger = require('./logger'); logger.levels('stdout', process.env.LOG_LEVEL); const settings = { shutdownTimeout: process.env.SHUTDOWN_TIMEOUT, http: { port: process.env.HTTP_PORT, }, redis: { uri: process.env.REDIS_URI, }, }; module.exports = settings;
  21. What is Quality? 23 Dima: process.env knows every env var.

    This is risky! Nikita: Then your project uses only 11 factors.
  22. IV. Backing services Treat backing services as attached resources

  23. What is Quality? 25 ▰ local and third party parity

    ▰ Use connection string is URL and can be used as locator/credentials ▰ Native Node.js module url has parse method ▰ Repeat III. Config one more time
  24. What is Quality? 26 Nice to have ▰ Tech stack

    for project or with strict versions ▰ For local development docker-compose file or minikube config file
  25. V. Build, release, run Strictly separate build and run stages

  26. What is Quality? 28 ▰ Artifact ▰ Build ▰ Release

    ▰ Run time ▰ Dry run
  27. What is Quality? 29 Node.js artifact ▰ N/A ▰ Docker

    ▰ Lambda zip ▰ Application Zip ▻ Big size ▻ node-gyp compiled code can be broken on another computer
  28. VI. Processes Execute the app as one or more stateless

  29. What is Quality? 31

  30. Awesome Pair! Docker and Node.js has a common thing –

    single process
  31. None
  32. VII. Port binding Export services via port binding

  33. What is Quality? 35 ▰ Don’t hardcode port at the

    code, use env vars ▰ Bootstrap should fail, if the port is not available ▰ Dockerfile EXPOSE directive depence on deploy, but 9229...
  34. VIII. Concurrency Scale out via the process model

  35. What is Quality? 37 ▰ Unix process model ▰ should

    never daemonize ▰ Use process manager like systemd/pm2/etc ▰ process and cluster are first class citizen
  36. IX. Disposability Maximize robustness with fast startup and graceful shutdown

  37. const server = app.listen(settings.port, () => {`Server started on

    port ${settings.port}`); }); function stopHandler(){`Stopping server on port ${settings.port}`); const timeout = setTimeout(() => {`Server on port ${settings.port} stop forcefully`); process.exit(1); }, settings.stopTimeout); server.close(() => {`Server on port ${settings.port} stopped`); clearTimeout(timeout); }); }; process.on('exit', (code) =>`Exit with code: ${code}`)); ['SIGTERM','SIGINT','SIGHUP'] .forEach(signal => process.on(signal, stopHandler);
  38. X. Dev/prod parity Keep development, staging, and production as similar

    as possible
  39. What is Quality? 41 ▰ Same backing services ▰ Same

    lib versions ▰ Same bla-bla for Reproducibility
  40. XI. Logs Treat logs as event streams

  41. What is Quality? 43 ▰ A twelve-factor app never concerns

    itself with routing or storage of its output stream ▰ Writes event stream, unbuffered, to stdout/stderr ▰ JSON format for simplification log parsing ▰ pino has this format from the box ▰ for local development use pino pretty
  42. stdout stderr

  43. XII. Admin processes Run admin/management tasks as one-off processes

  44. What is Quality? 46 ▰ Node.js has REPL, so be

    DevOps Engineer ▰ Check node_modules/.bin every script starts with #!/usr/bin/env node ▰ Write your own script or reuse packages ▰ Database migrations ▰ Your own CLI with typescript decorators with clime package

  46. 49 THANKS! Happy coding with 12 factors! You can find

    me on Twitter as @galk_in Slides are available at or at my site