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

How to Build 12-Factor Application in NodeJS Using Docker

Aditya Satrya
September 28, 2019

How to Build 12-Factor Application in NodeJS Using Docker

Nowadays, most applications are deployed on the cloud. It's important to build our application in cloud-native way so that it can gain the full potential of the cloud. The best practice to write cloud-native app is by following the 12-factor rule set, something published by Heroku in 2011 but still relevant today. In this talk, it will be discussed how to build a NodeJS application that follows 12-factor using Docker.

Aditya Satrya

September 28, 2019
Tweet

More Decks by Aditya Satrya

Other Decks in Technology

Transcript

  1. How to Build 12-Factor Application in NodeJS using Docker Aditya

    Satrya Head of IT Development Jabar Digital Service JSDay Indonesia 2019
  2. Outline 2 ▷ Cloud-native ▷ Docker ▷ Twelve-factor app ▷

    How to write NodeJS app that follows 12-factor
  3. Cloud-Native application Able to get the maximum benefit from cloud

    computing: ▷ Portability ▷ Scalable ▷ Resilient ▷ Minimize time & cost with automation ▷ Continuous deployment 8
  4. 9 Cloud-Native Trail-map 1. Containerization 2. CI/CD 3. Orchestration --below

    this are optional-- 4. Observability 5. Service Discovery 6. Networking & Policy 7. Distributed database & storage 8. Streaming & messaging 9. Container registry 10. Software distribution
  5. Containerization 12 ▷ a standard way to package your application's

    code, configurations, and dependencies into a single object. https://aws.amazon.com/containers/
  6. What is 12-Factor app? ▷ Best practices to build app

    optimized for the cloud (cloud-native) 18
  7. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 20 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  8. File:index.js var app = express(); ... app.get('/', function (req, res)

    { connection.query('SELECT * FROM names LIMIT 1' , function (err, rows, fields) { res.send('Hello ' + rows[0].first_name + ' ' + rows[0].last_name); }) }); app.listen(8000, function () { console.log('Server is listening on port 8000' ); }) 24
  9. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 26 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  10. I. One Codebase 28 ▷ Violation: ◦ Multiple app sharing

    one codebase ▷ Solution: ◦ Treat as dependency
  11. I. One Codebase 29 ▷ Violation: ◦ Different code for

    different version of an app ▷ Solution: ◦ Use git branch/tag for different version
  12. I. One Codebase 30 ▷ Benefit: ◦ Easy for automation

    (CI/CD) ◦ Encourage smaller codebase (build & run faster, improve maintainability)
  13. One Codebase, Many Deploys $ docker build -t asatrya/nodejs-12factor-app:1.0 .

    $ docker build -t asatrya/nodejs-12factor-app:2.0 . $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE asatrya/nodejs-12factor-app 1.0 ca4305291fb1 4 minutes ago 907MB asatrya/nodejs-12factor-app 2.0 eec4a2c8a951 2 minutes ago 907MB 33
  14. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 34 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  15. II. Explicitly declare and isolate dependencies 35 ▷ Never relies

    on implicit existence of system-wide packages ▷ Isolation
  16. II. Explicitly declare and isolate dependencies 36 ▷ Benefit: ◦

    Improve predictability ◦ Simplifies setup
  17. File:Dockerfile FROM node:10 # Create app directory RUN mkdir /app

    WORKDIR /app # Install app dependencies COPY package.json . RUN npm install COPY . . # Copy app source EXPOSE 8080 # Expose listened port CMD [ "node", "index.js" ] 39
  18. Build Docker Image $ docker build -t asatrya/nodejs-12factor-app:1.0 . $

    docker images REPOSITORY TAG IMAGE ID CREATED SIZE asatrya/nodejs-12factor-app 1.0 ca4305291fb1 4 minutes ago 907MB 40
  19. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 41 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  20. III. Store config in the environment 42 ▷ Config could

    be: ◦ Resource handles to backing services ◦ Credentials to external services ▷ Config varies across deploys, code does not
  21. III. Store config in the environment 43 ▷ Strict separation

    of config from code ▷ Litmus test: ◦ Ready to be made open source anytime?
  22. III. Store config in the environment 44 ▷ Violation: ◦

    Store config as constants in the code ▷ Solution: ◦ Store config as environment variables
  23. File:index.js ... var mysql = require('mysql'); var connection = mysql.createConnection({

    host: process.env.MYSQL_HOST, user: process.env.MYSQL_USER, password: process.env.MYSQL_PASSWORD, database: process.env.MYSQL_DATABASE, }); ... 45
  24. Run Container $ docker run --rm \ -e MYSQL_HOST=db \

    -e MYSQL_USER=dbuser \ -e MYSQL_PASSWORD=dbpassword \ -e MYSQL_DATABASE=dbname \ asatrya/nodejs-12factor-app:1.0 46
  25. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 47 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  26. ▷ Assume local resource are temporal and disposable ▷ Share-nothing

    architecture VI. Execute the app as stateless processes 48
  27. ▷ Violation: ◦ Store persistent data/files in local filesystem ▷

    Solution: ◦ Store in S3 VI. Execute the app as stateless processes 49
  28. ▷ Benefit: ◦ Easy to scale out ◦ Resilient VI.

    Execute the app as stateless processes 50
  29. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 51 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  30. IV. Treat backing services as attached resources 53 ▷ Able

    to attach/detach backing services without any code change
  31. IV. Treat backing services as attached resources 54 ▷ Benefit:

    ◦ Flexibility ◦ Resilience ◦ Loose coupling
  32. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 55 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  33. V. Strictly separate build and run stages 57 ▷ Violation:

    ◦ Include config values in build artefact ◦ Alter code when running app
  34. V. Strictly separate build and run stages 58 ▷ Benefit:

    ◦ Easy for rollback ◦ Promotes the separation of concerns
  35. Separate Build,Release & Run # build $ docker build -t

    asatrya/nodejs-12factor-app:1.0 . # release $ docker push asatrya/nodejs-12factor-app:1.0 # run $ docker run --rm \ -e MYSQL_HOST=db \ -e MYSQL_USER=dbuser \ -e MYSQL_PASSWORD=dbpassword \ -e MYSQL_DATABASE=dbname \ asatrya/nodejs-12factor-app:1.0 59
  36. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 60 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  37. X. Dev/prod parity 61 Traditional app 12-Factor App Code push

    to deploy Days Minutes/Hours Code authors vs code deployers Different people Same people Dev vs production environments Different Similar as possible
  38. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 63 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  39. ▷ your application might run as ◦ http://localhost:12001 on local

    ◦ http://192.168.1.10:2000 on staging ◦ http://app.company.com on production ▷ without having to change any code. VII. Export services via port binding 64
  40. ▷ Benefit: ◦ Your apps can be a backing services

    for another app ◦ Flexibility VII. Export services via port binding 65
  41. File:index.js var app = express(); ... app.get('/', function (req, res)

    { connection.query('SELECT * FROM names LIMIT 1' , function (err, rows, fields) { res.send('Hello ' + rows[0].first_name + ' ' + rows[0].last_name); }) }); app.listen(8000, function () { console.log('Server is listening on port 8000' ); }) 66
  42. Run Container $ docker run --rm \ -e MYSQL_HOST=db \

    -e MYSQL_USER=dbuser \ -e MYSQL_PASSWORD=dbpassword \ -e MYSQL_DATABASE=dbname \ -p 8001:8000 asatrya/nodejs-12factor-app:1.0 67
  43. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 69 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  44. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 72 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  45. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 74 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  46. XI. Treat logs as event streams 75 ▷ Write logs

    to stdout ▷ External system to collect logs into a centralized location
  47. Code I. One Codebase One codebase tracked in revision control,

    many deploys II. Dependencies Explicitly declare and isolate dependencies III. Config Store config in the environment VI. Processes Execute the app as one or more stateless processes 76 IV. Backing services Treat backing services as attached resources V. Build, release, run Strictly separate build and run stages X. Dev/prod parity Keep development, staging, and production as similar as possible VII. Port binding Export services via port binding VIII. Concurrency Scale out via the process model IX. Disposability Maximize robustness with fast startup and graceful shutdown XI. Logs Treat logs as event streams XII. Admin processes Run admin tasks as one-off processes Deploy Operate
  48. XII. Run admin tasks as one-off processes 77 ▷ Examples

    of administrative processes: ◦ Database migrations ◦ Interactive programming consoles (REPLs) ◦ Timed scripts (ex: batch job) ◦ Executes custom code only once