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

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

More Decks by Nikita Galkin

Other Decks in Programming


  1. 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
  2. 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
  3. 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 http://reg.example.com ▰ With a self-hosted repo, use add .npmrc to git
  4. 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
  5. 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"]
  6. What is Quality? 19 ▰ Config is not part of

    the artifact ▰ App could be made open source at any moment, without compromising any credentials.
  7. 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
  8. # .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://
  9. 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;
  10. What is Quality? 23 Dima: process.env knows every env var.

    This is risky! Nikita: Then your project uses only 11 factors.
  11. 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
  12. What is Quality? 26 Nice to have ▰ Tech stack

    for project or Readme.md with strict versions ▰ For local development docker-compose file or minikube config file
  13. 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
  14. 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...
  15. What is Quality? 37 ▰ Unix process model ▰ should

    never daemonize ▰ Use process manager like systemd/pm2/etc ▰ process and cluster are first class citizen
  16. 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);
  17. What is Quality? 41 ▰ Same backing services ▰ Same

    lib versions ▰ Same bla-bla for Reproducibility
  18. 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
  19. 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
  20. 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