<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: João Santos</title>
    <description>The latest articles on DEV Community by João Santos (@jvsa7_).</description>
    <link>https://dev.to/jvsa7_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F183031%2F9f78db74-6244-41f6-8c3e-36f09d4c8f6e.jpeg</url>
      <title>DEV Community: João Santos</title>
      <link>https://dev.to/jvsa7_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jvsa7_"/>
    <language>en</language>
    <item>
      <title>How did I shrink my NextJS Docker image by 90%?</title>
      <dc:creator>João Santos</dc:creator>
      <pubDate>Wed, 28 Sep 2022 15:06:24 +0000</pubDate>
      <link>https://dev.to/jvsa7_/how-i-reduced-my-nextjs-docker-image-in-80-1na2</link>
      <guid>https://dev.to/jvsa7_/how-i-reduced-my-nextjs-docker-image-in-80-1na2</guid>
      <description>&lt;p&gt;Hey Folks!&lt;/p&gt;

&lt;p&gt;Recently my team were working at a legacy NextJS project (next v10, without swc build, etc). In our infrastructure, we use AWS ECR and Kubernetes, so we build Docker Images of our applications.&lt;/p&gt;

&lt;p&gt;But... something wasn't right.&lt;/p&gt;

&lt;p&gt;Look at this image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frre4qks1p4rpzifn0hfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frre4qks1p4rpzifn0hfs.png" alt="Docker image size: 1.37gb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project were building a docker image with &lt;code&gt;1.37gb size!!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our CircleCI production workflow (&lt;code&gt;deploy&lt;/code&gt;) were lasting at least &lt;code&gt;8 minutes !!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fat7s7mnjcocm9xd7lb7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fat7s7mnjcocm9xd7lb7s.png" alt="Production pipeline 8 minutes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How did i resolve this issue?&lt;/p&gt;

&lt;p&gt;First i must &lt;code&gt;IDENTIFY&lt;/code&gt; why this were happening.&lt;/p&gt;

&lt;p&gt;Once the problem was identified...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why my docker image was getting bigger than &lt;code&gt;1gb?&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;R: Because we were copying all project files to docker. On &lt;code&gt;DockerFile&lt;/code&gt;, we were using &lt;code&gt;COPY . .&lt;/code&gt;, it's the same than say: &lt;code&gt;Docker, you must copy all of the project to docker imag, okay? And "Docker" says: Yes, sir.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;My old DockerFile.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This project, didn't had .dockerignore file too :(&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:14-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; / .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "yarn", "start" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How did i resolve this problem?
&lt;/h2&gt;

&lt;p&gt;I started to investigate about some solutions for this &lt;code&gt;BIG PROBLEM!!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I will describe my mindset flow to solution this problem.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Update NextJS for latest version&lt;br&gt;
Like i said before, this project were using nextjs 10! I updated for nextjs 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find some solutions on stackoverflow/github issues&lt;br&gt;
We must do it for every problem that u doesn't know how to solution immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find solutions on Nextjs docs/github.&lt;br&gt;
Here we go...&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Nextjs Output Standalone
&lt;/h2&gt;

&lt;p&gt;Since &lt;code&gt;Next 12&lt;/code&gt; we have &lt;code&gt;output standalone&lt;/code&gt; option in Next.JS, what's it?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;From NextJS website&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next.js can automatically create a standalone folder which copies only the necessary files for a production deployment including select files in node_modules.&lt;/p&gt;

&lt;p&gt;To leverage this automatic copying you can enable it in your next.config.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  output: 'standalone'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a folder at .next/standalone which can then be deployed on it's own without installing node_modules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands On
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Added .dockerignore file&lt;br&gt;
I added that folders that isn't necessary to the project run. (.github folder, storybook, mocks, models, jest, etc, ...)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modified NextJS config&lt;br&gt;
I added the &lt;code&gt;output: 'standalone'&lt;/code&gt; to next.config.js file, now, next would build in standalone mode, it would create a folder with only necessary files to the project run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modified DockerFile&lt;br&gt;
Before my &lt;code&gt;DockerFile&lt;/code&gt; were copying the entire project to the docker image, i changed it and now we're copying only the necessary files to our image, look below.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:14-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

// copying the `.next/standalone`, where's the necessary files for the production environment
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; .next/standalone .&lt;/span&gt;

// copying static files, like (images, javascript chunks, etc)

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; .next/static ./.next/static&lt;/span&gt;

// copying public assets (images, fonts, etc)
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; public ./public&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV production&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "node", "server.js" ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;Before these changes, our docker image size were close to &lt;code&gt;1.3gb&lt;/code&gt;, now...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgezp70wuhu2wqdnqm4si.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgezp70wuhu2wqdnqm4si.png" alt="Build size now it's 100mb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before these changs, our deploy pipeline were lasting &lt;code&gt;8 to 10minutes&lt;/code&gt;, now...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjakre05xajvhuxay6gp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjakre05xajvhuxay6gp.png" alt="Production pipeline now it's 2minutes"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Useful Links

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/docs/advanced-features/output-file-tracing" rel="noopener noreferrer"&gt;https://nextjs.org/docs/advanced-features/output-file-tracing&lt;/a&gt;
-&lt;a href="https://github.com/vercel/next.js/tree/canary/examples/with-docker" rel="noopener noreferrer"&gt;https://github.com/vercel/next.js/tree/canary/examples/with-docker&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;My github: &lt;a href="https://github.com/joaovsa7" rel="noopener noreferrer"&gt;https://github.com/joaovsa7&lt;/a&gt;&lt;br&gt;
LinkedIn: &lt;a href="https://linkedin.com/in/jvsa7" rel="noopener noreferrer"&gt;https://linkedin.com/in/jvsa7&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>docker</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
