Build a Twelve-Factor Node.js App with Docker

بواسطة: egghead.io

Overview

In this course we will take a simple Node.js app that connects to a MongoDB database and uses an Express web server, and learn how to setup a full software development deployment process as well as how to properly “Dockerize” the app.
We’ll step through setting up proper version control techniques, managing configuring within the environment, setting up proper build/deploy/run processes, and all with abiding by Docker best practices. We’ll also make sure our deployment is setup for scale, and have consistent development practices in place for reliable app deployments.

Syllabus

  • Summary & Concepts of the Twelve-Factor App
  • Pin Down NPM Package Versions with Yarn.lock
  • Use Git Flow as a Reliable Version Control Model
  • Manage Configuration Values with Environment Variables
  • Proxy Requests for Local and Remote Service Parity
  • Build, Release and Run Containers with Docker Compose
  • Run Stateless Docker Containers
  • Export Services with Docker Port Binding
  • Scale Docker Horizontally with Nginx Load Balancing
  • Ensure Containers Run with High-Availability
  • Run Consistent Dev, Stage & Prod Docker Environments
  • Pipe Log Output to STDOUT with Docker
  • Run One-Off Docker Containers

Taught by

Mark Shust

Build a Twelve-Factor Node.js App with Docker
الذهاب الي الدورة

Build a Twelve-Factor Node.js App with Docker

بواسطة: egghead.io

  • egghead.io
  • مدفوعة
  • الإنجليزية
  • متاح شهادة
  • متاح في أي وقت
  • الجميع
  • N/A
8.1.2PHP Version336msRequest Duration2MBMemory UsageGET ar/الدورات/{slug}Route
    • Booting (215ms)
    • Application (120ms)
    • 1 x Booting (64.11%)
      215.31ms
      1 x Application (35.65%)
      119.73ms
      14 templates were rendered
      • public.courses.show (resources/views/public/courses/show.blade.php)3bladefile
        Params
        0
        course
        1
        links
        2
        config
      • public.courses.partials.breadcrumbs (resources/views/public/courses/partials/breadcrumbs.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.heading (resources/views/public/courses/partials/heading.blade.php)7bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        classes
      • public.courses.partials.details (resources/views/public/courses/partials/details.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.breadcrumbs (resources/views/public/courses/partials/breadcrumbs.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.heading (resources/views/public/courses/partials/heading.blade.php)7bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        classes
      • public.layouts.main (resources/views/public/layouts/main.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.layouts.partials.meta (resources/views/public/layouts/partials/meta.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.layouts.partials.navbar (resources/views/public/layouts/partials/navbar.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.auth.profile.partials.links (resources/views/public/auth/profile/partials/links.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.layouts.partials.flash-session (resources/views/public/layouts/partials/flash-session.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      uri
      GET ar/الدورات/{slug}
      middleware
      web, localize:ar
      controller
      App\Http\Controllers\CourseController@show
      as
      ar.courses.show
      namespace
      prefix
      /ar
      where
      file
      app/Http/Controllers/CourseController.php:17-35
      6 statements were executed5.96ms
      • select * from `courses` where `slug_ar` = 'build-a-twelve-factor-node.js-app-with-docker' limit 1
        4.81ms/app/Http/Controllers/CourseController.php:20corspedia
        Metadata
        Bindings
        • 0. build-a-twelve-factor-node.js-app-with-docker
        Backtrace
        • 17. /app/Http/Controllers/CourseController.php:20
        • 18. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 19. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 20. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • update `courses` set `visitors` = `visitors` + 1, `courses`.`updated_at` = '2025-04-09 11:19:42' where `id` = 2115
        330μs/app/Http/Controllers/CourseController.php:21corspedia
        Metadata
        Bindings
        • 0. 2025-04-09 11:19:42
        • 1. 2115
        Backtrace
        • 17. /app/Http/Controllers/CourseController.php:21
        • 18. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 19. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 20. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select `id`, `name_en`, `name_ar`, `topic_id`, `slug_en`, `slug_ar` from `subjects` where `subjects`.`id` in (99)
        200μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 20. /app/Http/Controllers/CourseController.php:23
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 22. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 23. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 24. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select `id`, `name_en`, `name_ar`, `slug_en`, `slug_ar` from `topics` where `topics`.`id` in (1)
        170μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 25. /app/Http/Controllers/CourseController.php:23
        • 26. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 27. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 28. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 29. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select * from `providers` where `providers`.`id` in (29) and `providers`.`deleted_at` is null
        210μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 20. /app/Http/Controllers/CourseController.php:23
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 22. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 23. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 24. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select * from `html_files` where `html_files`.`id` = 2106 limit 1
        240μs/app/Models/Course.php:84corspedia
        Metadata
        Bindings
        • 0. 2106
        Backtrace
        • 21. /app/Models/Course.php:84
        • 28. view::public.courses.show:29
        • 30. /vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:125
        • 31. /vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php:58
        • 32. /vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php:72
      App\Models\HtmlFile
      1
      App\Models\Provider
      1
      App\Models\Topic
      1
      App\Models\Subject
      1
      App\Models\Course
      1
        _token
        NQT1PZ7cRSAWTSteRhf6Plc7WTVQI1C5koOwjY90
        locale
        ar
        _previous
        array:1 [ "url" => "https://www.corspedia.com/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/build-...
        _flash
        array:2 [ "old" => [] "new" => [] ]
        PHPDEBUGBAR_STACK_DATA
        []
        path_info
        /ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/build-a-twelve-factor-node.js-app-with-docker
        status_code
        200
        
        status_text
        OK
        format
        html
        content_type
        text/html; charset=UTF-8
        request_query
        []
        
        request_request
        []
        
        request_headers
        0 of 0
        array:24 [ "cf-ipcountry" => array:1 [ 0 => "US" ] "cf-connecting-ip" => array:1 [ 0 => "3.15.209.38" ] "cdn-loop" => array:1 [ 0 => "cloudflare; loops=1" ] "x-forwarded-proto" => array:1 [ 0 => "https" ] "cf-visitor" => array:1 [ 0 => "{"scheme":"https"}" ] "sec-fetch-site" => array:1 [ 0 => "none" ] "accept" => array:1 [ 0 => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" ] "user-agent" => array:1 [ 0 => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)" ] "upgrade-insecure-requests" => array:1 [ 0 => "1" ] "sec-ch-ua-platform" => array:1 [ 0 => ""Windows"" ] "sec-ch-ua-mobile" => array:1 [ 0 => "?0" ] "sec-ch-ua" => array:1 [ 0 => ""HeadlessChrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"" ] "cache-control" => array:1 [ 0 => "no-cache" ] "pragma" => array:1 [ 0 => "no-cache" ] "sec-fetch-dest" => array:1 [ 0 => "document" ] "cf-ray" => array:1 [ 0 => "92d99c68aa244c99-MSP" ] "accept-encoding" => array:1 [ 0 => "gzip, br" ] "priority" => array:1 [ 0 => "u=0, i" ] "sec-fetch-user" => array:1 [ 0 => "?1" ] "sec-fetch-mode" => array:1 [ 0 => "navigate" ] "x-forwarded-for" => array:1 [ 0 => "3.15.209.38" ] "host" => array:1 [ 0 => "www.corspedia.com" ] "content-length" => array:1 [ 0 => "" ] "content-type" => array:1 [ 0 => "" ] ]
        request_server
        0 of 0
        array:50 [ "USER" => "www-data" "HOME" => "/var/www" "HTTP_CF_IPCOUNTRY" => "US" "HTTP_CF_CONNECTING_IP" => "3.15.209.38" "HTTP_CDN_LOOP" => "cloudflare; loops=1" "HTTP_X_FORWARDED_PROTO" => "https" "HTTP_CF_VISITOR" => "{"scheme":"https"}" "HTTP_SEC_FETCH_SITE" => "none" "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" "HTTP_USER_AGENT" => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)" "HTTP_UPGRADE_INSECURE_REQUESTS" => "1" "HTTP_SEC_CH_UA_PLATFORM" => ""Windows"" "HTTP_SEC_CH_UA_MOBILE" => "?0" "HTTP_SEC_CH_UA" => ""HeadlessChrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"" "HTTP_CACHE_CONTROL" => "no-cache" "HTTP_PRAGMA" => "no-cache" "HTTP_SEC_FETCH_DEST" => "document" "HTTP_CF_RAY" => "92d99c68aa244c99-MSP" "HTTP_ACCEPT_ENCODING" => "gzip, br" "HTTP_PRIORITY" => "u=0, i" "HTTP_SEC_FETCH_USER" => "?1" "HTTP_SEC_FETCH_MODE" => "navigate" "HTTP_X_FORWARDED_FOR" => "3.15.209.38" "HTTP_HOST" => "www.corspedia.com" "REDIRECT_STATUS" => "200" "SERVER_NAME" => "corspedia.com" "SERVER_PORT" => "443" "SERVER_ADDR" => "141.95.147.152" "REMOTE_USER" => "" "REMOTE_PORT" => "19752" "REMOTE_ADDR" => "141.101.109.222" "SERVER_SOFTWARE" => "nginx/1.18.0" "GATEWAY_INTERFACE" => "CGI/1.1" "HTTPS" => "on" "REQUEST_SCHEME" => "https" "SERVER_PROTOCOL" => "HTTP/2.0" "DOCUMENT_ROOT" => "/var/www/corspedia/public" "DOCUMENT_URI" => "/index.php" "REQUEST_URI" => "/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/build-a-twelve-factor-node.js-app-with-docker" "SCRIPT_NAME" => "/index.php" "CONTENT_LENGTH" => "" "CONTENT_TYPE" => "" "REQUEST_METHOD" => "GET" "QUERY_STRING" => "" "SCRIPT_FILENAME" => "/var/www/corspedia/public/index.php" "PATH_INFO" => "" "FCGI_ROLE" => "RESPONDER" "PHP_SELF" => "/index.php" "REQUEST_TIME_FLOAT" => 1744197582.4963 "REQUEST_TIME" => 1744197582 ]
        request_cookies
        []
        
        response_headers
        0 of 0
        array:5 [ "content-type" => array:1 [ 0 => "text/html; charset=UTF-8" ] "cache-control" => array:1 [ 0 => "no-cache, private" ] "date" => array:1 [ 0 => "Wed, 09 Apr 2025 11:19:42 GMT" ] "set-cookie" => array:2 [ 0 => "XSRF-TOKEN=eyJpdiI6IlZ1Y2hVUDloNWZ3SkJsSk95cTR6VFE9PSIsInZhbHVlIjoiZjkxQUxUL1VxSkRlU2lSWWZldG5zdFE4cEh2UHd0U3JsVlN0WUNtbTBkZFpTTFpkZC9oZkpVWDlUVXFCOEM3d3M1M1RtQjdyQXBHKzBXZ0VsNS8rVmloaGhEMmhWdHZaZUhidTNhSmRzYzc0Yi9EN2Z5MFh4WnZHeFg2WVlsQWMiLCJtYWMiOiI0NzUxMzk2ODZhMzdhMTUxMGUyMWYyN2U1NDY0YzE4YjQyZGNjOWIxMTAyN2VjYzgxM2FhYzIyZDZiYzEyY2VkIiwidGFnIjoiIn0%3D; expires=Wed, 09 Apr 2025 13:19:42 GMT; Max-Age=7200; path=/; samesite=laxXSRF-TOKEN=eyJpdiI6IlZ1Y2hVUDloNWZ3SkJsSk95cTR6VFE9PSIsInZhbHVlIjoiZjkxQUxUL1VxSkRlU2lSWWZldG5zdFE4cEh2UHd0U3JsVlN0WUNtbTBkZFpTTFpkZC9oZkpVWDlUVXFCOEM3d3M1M1RtQ" 1 => "laravel_session=eyJpdiI6IjFWSmhWNG5PWHU2Q3dHajQzQVpLcmc9PSIsInZhbHVlIjoiRW1kRGZKNGw3bEUyZTRsM0lDSEFNelNOMVoxdllKZ3NzVDArVDdaWWIxVFdnWUluRGdlcHlBQVhkRXZ2bDFYZ2Q5R2ZzR3U5Vlgwa0c2allzZWJIL0ZCQ2tEVW9kMldYR3ZkcEpDQzA0Z1pDVGc0MDJrWHNudEo3TXZXM2lkT2YiLCJtYWMiOiIyM2M1NmE5Y2JhNTQ1MDViZWE2MjBjMzNhYmU5M2RlZTY3MDZjNjY4MzFkOWQ0MzU2MWNlNWJkNmNiNjlmOGUxIiwidGFnIjoiIn0%3D; expires=Wed, 09 Apr 2025 13:19:42 GMT; Max-Age=7200; path=/; httponly; samesite=laxlaravel_session=eyJpdiI6IjFWSmhWNG5PWHU2Q3dHajQzQVpLcmc9PSIsInZhbHVlIjoiRW1kRGZKNGw3bEUyZTRsM0lDSEFNelNOMVoxdllKZ3NzVDArVDdaWWIxVFdnWUluRGdlcHlBQVhkRXZ2bDFYZ2Q5" ] "Set-Cookie" => array:2 [ 0 => "XSRF-TOKEN=eyJpdiI6IlZ1Y2hVUDloNWZ3SkJsSk95cTR6VFE9PSIsInZhbHVlIjoiZjkxQUxUL1VxSkRlU2lSWWZldG5zdFE4cEh2UHd0U3JsVlN0WUNtbTBkZFpTTFpkZC9oZkpVWDlUVXFCOEM3d3M1M1RtQjdyQXBHKzBXZ0VsNS8rVmloaGhEMmhWdHZaZUhidTNhSmRzYzc0Yi9EN2Z5MFh4WnZHeFg2WVlsQWMiLCJtYWMiOiI0NzUxMzk2ODZhMzdhMTUxMGUyMWYyN2U1NDY0YzE4YjQyZGNjOWIxMTAyN2VjYzgxM2FhYzIyZDZiYzEyY2VkIiwidGFnIjoiIn0%3D; expires=Wed, 09-Apr-2025 13:19:42 GMT; path=/XSRF-TOKEN=eyJpdiI6IlZ1Y2hVUDloNWZ3SkJsSk95cTR6VFE9PSIsInZhbHVlIjoiZjkxQUxUL1VxSkRlU2lSWWZldG5zdFE4cEh2UHd0U3JsVlN0WUNtbTBkZFpTTFpkZC9oZkpVWDlUVXFCOEM3d3M1M1RtQ" 1 => "laravel_session=eyJpdiI6IjFWSmhWNG5PWHU2Q3dHajQzQVpLcmc9PSIsInZhbHVlIjoiRW1kRGZKNGw3bEUyZTRsM0lDSEFNelNOMVoxdllKZ3NzVDArVDdaWWIxVFdnWUluRGdlcHlBQVhkRXZ2bDFYZ2Q5R2ZzR3U5Vlgwa0c2allzZWJIL0ZCQ2tEVW9kMldYR3ZkcEpDQzA0Z1pDVGc0MDJrWHNudEo3TXZXM2lkT2YiLCJtYWMiOiIyM2M1NmE5Y2JhNTQ1MDViZWE2MjBjMzNhYmU5M2RlZTY3MDZjNjY4MzFkOWQ0MzU2MWNlNWJkNmNiNjlmOGUxIiwidGFnIjoiIn0%3D; expires=Wed, 09-Apr-2025 13:19:42 GMT; path=/; httponlylaravel_session=eyJpdiI6IjFWSmhWNG5PWHU2Q3dHajQzQVpLcmc9PSIsInZhbHVlIjoiRW1kRGZKNGw3bEUyZTRsM0lDSEFNelNOMVoxdllKZ3NzVDArVDdaWWIxVFdnWUluRGdlcHlBQVhkRXZ2bDFYZ2Q5" ] ]
        session_attributes
        0 of 0
        array:5 [ "_token" => "NQT1PZ7cRSAWTSteRhf6Plc7WTVQI1C5koOwjY90" "locale" => "ar" "_previous" => array:1 [ "url" => "https://www.corspedia.com/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/build-a-twelve-factor-node.js-app-with-docker" ] "_flash" => array:2 [ "old" => [] "new" => [] ] "PHPDEBUGBAR_STACK_DATA" => [] ]