Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Twelve-Factor App for Node.js Developers

The Twelve-Factor App for Node.js Developers

Nikita Galkin

February 27, 2019

More Decks by Nikita Galkin

Other Decks in Programming


  1. 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 2
  2. What is Quality? 5 Motivation ▰ Reduce the onboarding time

    ▰ A common language with DevOps Engineers ▰ Scale/Cloud/Production/etc -ready
  3. What is Quality? 6 Talk Structure ▰ Factor ▰ RTFM

    ▰ how to implement using Node.js ▰ exclusion cases or hacks
  4. What is Quality? 8 One codebase tracked in revision control,

    many deploys ▰ App vs Distributed System ▰ Code sharing by dependency manager.
  5. What is Quality? 9 How to match codebase and application

    at env? ▰ semver ▰ version in package.json ▰ git tag ▰ git describe --tag Example 2.2.0-44-g9f84663
  6. What is Quality? 10 I. Codebase ▰ BE & FE

    aka Full-stack repo ▰ App & lambda from one src ▰ Monorepo
  7. What is Quality? 12 Explicitly declare and isolate dependencies ▰

    declaration VS isolation ▰ never relies on implicit existence ▰ system tool can be a dependency
  8. What is Quality? 13 Package.json ▰ avoid npm install -g

    ... ▰ package-lock.json should published in git ▰ node & npm versions fixed at Tech Stack or you will have package-lock diff war ▰ post-install script is a good place for hacking node_modules
  9. What is Quality? 15 Shared code ▰ 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 http://reg.example.com ▰ With a self-hosted repo, use add .npmrc to git
  10. What is Quality? 17 node_modules hacks ▰ Embedded or lambda:

    webpack ▰ Docker ▻ npm install --production ▻ npm prune --production ▻ node-prune ▻ docker in docker
  11. FROM node:10.15-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 yarn.lock $APP_WORKDIR WORKDIR $APP_WORKDIR RUN yarn install COPY . $APP_WORKDIR RUN yarn build RUN rm -rf tsconfig.json src RUN apk del build-deps RUN yarn install --production RUN yarn cache clean EXPOSE 3000 CMD ["node", "dist/index.js"]
  12. What is Quality? 20 Store config in the environment ▰

    Config is not part of the artifact ▰ could be made open source at any moment, without compromising any credentials.
  13. What is Quality? 21 .env ▰ Use .env file for

    local development ▰ Use .env.example file for description ▰ Use environment variables for any other environment ▰ Don’t use default config values in your code ▰ Break your start process if any value missed
  14. # .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://
  15. 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;
  16. What is Quality? 24 Dima: process.env knows every env var.

    This is risky! Nikita: Then your project uses only 11 factors.
  17. What is Quality? 26 Treat backing services as attached resources

    ▰ local and third party parity ▰ Attach URL or other locator/credentials stored in the config
  18. What is Quality? 27 Nice to have ▰ Tech stack

    for project or Readme.md with strict versions ▰ For local development docker-compose file or minikube config file
  19. What is Quality? 29 Strictly separate build and run stages

    ▰ Artifact ▰ Build ▰ Release ▰ Run time ▰ Dry run
  20. What is Quality? 30 Node.js artifact ▰ N/A ▰ Docker

    ▰ Lambda zip ▰ Application Zip ▻ Big size ▻ node-gyp compiled code can be broken on another computer
  21. What is Quality? 32 Execute the app as one or

    more stateless processes ▰ stateless ▰ share-nothing ▰ state stored at backing-service
  22. What is Quality? 36 ▰ Don’t hardcode port at the

    code, use env vars ▰ Bootstrap should fail, if the port is not available ▰ Dockerfile EXPOSE
  23. What is Quality? 38 Scale out via the process model

    ▰ Unix ▰ process ▰ should never daemonize ▰ Use process manager like systemd
  24. const server = app.listen(settings.port, () => { logger.info(`Server started on

    port ${settings.port}`); }); function stopHandler(){ logger.info(`Stopping server on port ${settings.port}`); const timeout = setTimeout(() => { logger.info(`Server on port ${settings.port} stop forcefully`); process.exit(1); }, settings.stopTimeout); server.close(() => { logger.info(`Server on port ${settings.port} stopped`); clearTimeout(timeout); }); }; process.on('exit', (code) => logger.info(`Exit with code: ${code}`)); ['SIGTERM','SIGINT','SIGHUP'] .forEach(signal => process.on(signal, stopHandler);
  25. What is Quality? 42 ▰ Same backing services ▰ Same

    lib versions ▰ Same bla-bla for Reproducibility
  26. What is Quality? 44 ▰ 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 ▰ bunyan has this format from the box ▰ for local development npm start | bunyan -o short
  27. What is Quality? 47 ▰ Node.js has REPL ▰ Check

    node_modules/.bin every script starts with #!/usr/bin/env node ▰ Write your own script or reuse packages ▰ Use npx, for example npx https://gist.github.com/galkin/9b54683ec251d77b26fa4c7feec46df2
  28. 49 THANKS! Happy coding with 12 factors! You can find

    me on Twitter as @galk_in Slides are available at speakerdeck.com/galkin or at my site galk.in