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

Avatar for Nikita Galkin

Nikita Galkin

February 27, 2019
Tweet

More Decks by Nikita Galkin

Other Decks in Programming

Transcript

  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://127.0.0.1:6379
  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