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

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

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

Avatar for Nikita Galkin

Nikita Galkin

October 05, 2019
Tweet

More Decks by Nikita Galkin

Other Decks in Programming

Transcript

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