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
Tweet

More Decks by Nikita Galkin

Other Decks in Programming

Transcript

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

    View full-size slide

  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

    View full-size slide

  3. 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

    View full-size slide

  4. 12factor.net

    View full-size slide

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

    View full-size slide

  6. What is Quality?
    9

    View full-size slide

  7. 11
    Scoped packages

    View full-size slide

  8. 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

    View full-size slide

  9. II. Dependencies
    Explicitly declare
    and isolate dependencies

    View full-size slide

  10. 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

    View full-size slide

  11. What is Quality?
    16

    View full-size slide

  12. 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"]

    View full-size slide

  13. III. Config
    Store config
    in the environment

    View full-size slide

  14. What is Quality?
    19
    ▰ Config is not part of the
    artifact
    ▰ App could be made open
    source at any moment,
    without compromising
    any credentials.

    View full-size slide

  15. 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

    View full-size slide

  16. # .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

    View full-size slide

  17. 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;

    View full-size slide

  18. What is Quality?
    23
    Dima: process.env knows
    every env var. This is
    risky!
    Nikita: Then your project
    uses only 11 factors.

    View full-size slide

  19. IV. Backing services
    Treat backing services
    as attached resources

    View full-size slide

  20. 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

    View full-size slide

  21. 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

    View full-size slide

  22. V. Build, release, run
    Strictly separate build
    and run stages

    View full-size slide

  23. What is Quality?
    28
    ▰ Artifact
    ▰ Build
    ▰ Release
    ▰ Run time
    ▰ Dry run

    View full-size slide

  24. 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

    View full-size slide

  25. VI. Processes
    Execute the app as one or
    more stateless processes

    View full-size slide

  26. What is Quality?
    31

    View full-size slide

  27. Awesome Pair!
    Docker and Node.js
    has a common thing
    – single process

    View full-size slide

  28. VII. Port binding
    Export services
    via port binding

    View full-size slide

  29. 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...

    View full-size slide

  30. VIII. Concurrency
    Scale out via
    the process model

    View full-size slide

  31. What is Quality?
    37
    ▰ Unix process model
    ▰ should never daemonize
    ▰ Use process manager like
    systemd/pm2/etc
    ▰ process and cluster are first
    class citizen

    View full-size slide

  32. IX. Disposability
    Maximize robustness with
    fast startup and graceful
    shutdown

    View full-size slide

  33. 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);

    View full-size slide

  34. X. Dev/prod parity
    Keep development,
    staging, and production as
    similar as possible

    View full-size slide

  35. What is Quality?
    41
    ▰ Same backing services
    ▰ Same lib versions
    ▰ Same bla-bla for
    Reproducibility

    View full-size slide

  36. XI. Logs
    Treat logs
    as event streams

    View full-size slide

  37. 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

    View full-size slide

  38. stdout stderr

    View full-size slide

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

    View full-size slide

  40. 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

    View full-size slide

  41. 12factor.net

    View full-size slide

  42. 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

    View full-size slide