{"id":1856,"date":"2022-02-10T18:32:12","date_gmt":"2022-02-10T18:32:12","guid":{"rendered":"https:\/\/takeondevops.com\/?p=1856"},"modified":"2022-02-10T18:32:17","modified_gmt":"2022-02-10T18:32:17","slug":"node-container-images-using-dockerfile","status":"publish","type":"post","link":"https:\/\/takeondevops.com\/?p=1856","title":{"rendered":"Creating Node(react) Container Images using Dockerfile"},"content":{"rendered":"\n<p>Okay. My first experience with Dockerfile wasn&#8217;t all that pleasant. But every dark cloud has a silver lining&#x1f642;. It made me more curious about them and led me to practice\/self study more. The source code used in this post is <a href=\"https:\/\/github.com\/ihsanizwer\/covid19-dash-sl.git\">here<\/a>. If you want to learn more on how this react app works as it is(without using containers) you can check out <a href=\"https:\/\/takeondevops.com\/?p=325\">this<\/a> post.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"let-s-talk-dockerfile\">Let&#8217;s talk Dockerfile<\/h2>\n\n\n\n<p>Below is the Dockerfile that we will peruse.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM node:12-alpine\r\nCOPY package.json .\/\r\nCOPY yarn.lock .\/\r\nRUN npm install node-sass@4.13\r\nRUN yarn install\r\nCOPY . .\r\nCMD &#91;\"yarn\",\"start\"]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"why-12-alpine\">Why 12-alpine?<\/h3>\n\n\n\n<p> The answer to that is two fold. Firstly, alpine images are smaller in size(some of them are like 1\/10th the size of an original image.). In our case, I tried creating an Dockerfile based image using a vanilla node image. This resulted in an image that is just over 900MB. When we use an alpine image here, the resulting image is a little over 400MB. Which is like half the size. Once we upload this image to Dockerhub, the size reduces to be over 300MB. Larger image sizes means, longer time to build and it takes up more space in the container registry. So as long as we are getting the same functionality, we can go for an alpine version.<\/p>\n\n\n\n<p>The second part to the same question above is on why the version 12 of node is being used. This is because it is one of the few versions that support the <code>node-sass<\/code> package in our <code>package.json<\/code> file. While we are at it, let&#8217;s look at why the <code>node-sass<\/code> package is installed separately before the <code>npm install<\/code> command. Again, that is because of a version conflict and not running as it is will result in an error.  You can read more about this on <a href=\"https:\/\/stackoverflow.com\/questions\/45801457\/node-js-python-not-found-exception-due-to-node-sass-and-node-gyp\">stackoverflow<\/a>. Gopal&#8217;s comment in there is what helped me on this.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"why-so-many-copy-commands\">Why so many Copy commands? <\/h3>\n\n\n\n<p>Why not just <code>Copy . . <\/code>? (Which would copy everything). Yes we can just use only <code>Copy . .<\/code> and that will copy over the <code>yarn.lock<\/code> and <code>package.json<\/code> as well. The reason why we write this separately is so that if there were no changes in the <code>yarn.lock<\/code> and <code>package.json<\/code> files (No changes in the dependencies), then docker will use the cache and the build will be much faster. This means docker wouldn&#8217;t have to build the image from scratch every time we do a build. Suppose we do have only just  <code>Copy . .<\/code>, then even if we make a slight change in the repo, it will have to build the image from scratch(Not taking advantage of the cache). <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"what-else\">What else?<\/h3>\n\n\n\n<p>Another important thing is sequence. The <code>Copy . .<\/code> needs to be under the <code>yarn install<\/code> command. If the <code>Copy . .<\/code> command sits above the <code>yarn install<\/code> command, then it would defeat the purpose of having separate copy commands. (Caching wouldn&#8217;t work and the builds will take longer time suppose there is a slight change in anything that is copied over.)<\/p>\n\n\n\n<p>Well that is it for this short blog. Pretty sure there can be more improvements to the Dockerfile. I will try to keep you posted if I find anything. Next time I hope to write another short blog on <code>docker-compose<\/code>. Until next time &#x1f44b;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Okay. My first experience with Dockerfile wasn&#8217;t all that pleasant. But every dark cloud has a silver lining&#x1f642;. It made me more curious about them and led me to practice\/self study more. The source code used in this post is here. If you want to learn more on how this react app works as it [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[3,4,6,1],"tags":[],"class_list":["post-1856","post","type-post","status-publish","format-standard","hentry","category-dev","category-featured","category-network","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Creating Node(react) Container Images using Dockerfile - Take On Devops<\/title>\n<meta name=\"description\" content=\"In this short blog, we will take a look at a Dockerfile written for a React\/Node application. You can follow along by downloading the code.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/takeondevops.com\/?p=1856\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating Node(react) Container Images using Dockerfile - Take On Devops\" \/>\n<meta property=\"og:description\" content=\"In this short blog, we will take a look at a Dockerfile written for a React\/Node application. You can follow along by downloading the code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/takeondevops.com\/?p=1856\" \/>\n<meta property=\"og:site_name\" content=\"Take On Devops\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-10T18:32:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-10T18:32:17+00:00\" \/>\n<meta name=\"author\" content=\"ihsan izwer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"ihsan izwer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856\"},\"author\":{\"name\":\"ihsan izwer\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/#\\\/schema\\\/person\\\/465f2fb632235eb4079002754cd66aeb\"},\"headline\":\"Creating Node(react) Container Images using Dockerfile\",\"datePublished\":\"2022-02-10T18:32:12+00:00\",\"dateModified\":\"2022-02-10T18:32:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856\"},\"wordCount\":510,\"articleSection\":[\"Dev\",\"Featured\",\"Network\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856\",\"url\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856\",\"name\":\"Creating Node(react) Container Images using Dockerfile - Take On Devops\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/takeondevops.com\\\/#website\"},\"datePublished\":\"2022-02-10T18:32:12+00:00\",\"dateModified\":\"2022-02-10T18:32:17+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/takeondevops.com\\\/#\\\/schema\\\/person\\\/465f2fb632235eb4079002754cd66aeb\"},\"description\":\"In this short blog, we will take a look at a Dockerfile written for a React\\\/Node application. You can follow along by downloading the code.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/takeondevops.com\\\/?p=1856\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/?p=1856#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/takeondevops.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating Node(react) Container Images using Dockerfile\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/#website\",\"url\":\"https:\\\/\\\/takeondevops.com\\\/\",\"name\":\"Take On Devops\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/takeondevops.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/takeondevops.com\\\/#\\\/schema\\\/person\\\/465f2fb632235eb4079002754cd66aeb\",\"name\":\"ihsan izwer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g\",\"caption\":\"ihsan izwer\"},\"url\":\"https:\\\/\\\/takeondevops.com\\\/?author=3\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Creating Node(react) Container Images using Dockerfile - Take On Devops","description":"In this short blog, we will take a look at a Dockerfile written for a React\/Node application. You can follow along by downloading the code.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/takeondevops.com\/?p=1856","og_locale":"en_US","og_type":"article","og_title":"Creating Node(react) Container Images using Dockerfile - Take On Devops","og_description":"In this short blog, we will take a look at a Dockerfile written for a React\/Node application. You can follow along by downloading the code.","og_url":"https:\/\/takeondevops.com\/?p=1856","og_site_name":"Take On Devops","article_published_time":"2022-02-10T18:32:12+00:00","article_modified_time":"2022-02-10T18:32:17+00:00","author":"ihsan izwer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"ihsan izwer","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/takeondevops.com\/?p=1856#article","isPartOf":{"@id":"https:\/\/takeondevops.com\/?p=1856"},"author":{"name":"ihsan izwer","@id":"https:\/\/takeondevops.com\/#\/schema\/person\/465f2fb632235eb4079002754cd66aeb"},"headline":"Creating Node(react) Container Images using Dockerfile","datePublished":"2022-02-10T18:32:12+00:00","dateModified":"2022-02-10T18:32:17+00:00","mainEntityOfPage":{"@id":"https:\/\/takeondevops.com\/?p=1856"},"wordCount":510,"articleSection":["Dev","Featured","Network"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/takeondevops.com\/?p=1856","url":"https:\/\/takeondevops.com\/?p=1856","name":"Creating Node(react) Container Images using Dockerfile - Take On Devops","isPartOf":{"@id":"https:\/\/takeondevops.com\/#website"},"datePublished":"2022-02-10T18:32:12+00:00","dateModified":"2022-02-10T18:32:17+00:00","author":{"@id":"https:\/\/takeondevops.com\/#\/schema\/person\/465f2fb632235eb4079002754cd66aeb"},"description":"In this short blog, we will take a look at a Dockerfile written for a React\/Node application. You can follow along by downloading the code.","breadcrumb":{"@id":"https:\/\/takeondevops.com\/?p=1856#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/takeondevops.com\/?p=1856"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/takeondevops.com\/?p=1856#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/takeondevops.com\/"},{"@type":"ListItem","position":2,"name":"Creating Node(react) Container Images using Dockerfile"}]},{"@type":"WebSite","@id":"https:\/\/takeondevops.com\/#website","url":"https:\/\/takeondevops.com\/","name":"Take On Devops","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/takeondevops.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/takeondevops.com\/#\/schema\/person\/465f2fb632235eb4079002754cd66aeb","name":"ihsan izwer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c82c3d13c92d77259746074978cb7d498778b44914dea60ad0367dec237c349f?s=96&d=mm&r=g","caption":"ihsan izwer"},"url":"https:\/\/takeondevops.com\/?author=3"}]}},"jetpack_featured_media_url":"","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/posts\/1856","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/takeondevops.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1856"}],"version-history":[{"count":4,"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/posts\/1856\/revisions"}],"predecessor-version":[{"id":1860,"href":"https:\/\/takeondevops.com\/index.php?rest_route=\/wp\/v2\/posts\/1856\/revisions\/1860"}],"wp:attachment":[{"href":"https:\/\/takeondevops.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/takeondevops.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/takeondevops.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}