Hey Folks!
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.
But... something wasn't right.
Look at this image.
This project were building a docker image with 1.37gb size!!
Our CircleCI production workflow (deploy
) were lasting at least 8 minutes !!
How did i resolve this issue?
First i must IDENTIFY
why this were happening.
Once the problem was identified...
Why my docker image was getting bigger than 1gb?
R: Because we were copying all project files to docker. On DockerFile
, we were using COPY . .
, it's the same than say: Docker, you must copy all of the project to docker imag, okay? And "Docker" says: Yes, sir.
My old DockerFile.
This project, didn't had .dockerignore file too :(
FROM node:14-alpine
WORKDIR /usr/src/app
COPY / .
EXPOSE 3000
CMD [ "yarn", "start" ]
How did i resolve this problem?
I started to investigate about some solutions for this BIG PROBLEM!!
I will describe my mindset flow to solution this problem.
Update NextJS for latest version
Like i said before, this project were using nextjs 10! I updated for nextjs 12.Find some solutions on stackoverflow/github issues
We must do it for every problem that u doesn't know how to solution immediately.Find solutions on Nextjs docs/github.
Here we go...
Nextjs Output Standalone
Since Next 12
we have output standalone
option in Next.JS, what's it?
From NextJS website
Next.js can automatically create a standalone folder which copies only the necessary files for a production deployment including select files in node_modules.
To leverage this automatic copying you can enable it in your next.config.js:
module.exports = {
output: 'standalone'
}
This will create a folder at .next/standalone which can then be deployed on it's own without installing node_modules.
Hands On
Added .dockerignore file
I added that folders that isn't necessary to the project run. (.github folder, storybook, mocks, models, jest, etc, ...)Modified NextJS config
I added theoutput: 'standalone'
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.Modified DockerFile
Before myDockerFile
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.
FROM node:14-alpine
WORKDIR /usr/src/app
// copying the `.next/standalone`, where's the necessary files for the production environment
COPY .next/standalone .
// copying static files, like (images, javascript chunks, etc)
COPY .next/static ./.next/static
// copying public assets (images, fonts, etc)
COPY public ./public
ENV NODE_ENV production
EXPOSE 3000
CMD [ "node", "server.js" ]
Result
Before these changes, our docker image size were close to 1.3gb
, now...
Before these changs, our deploy pipeline were lasting 8 to 10minutes
, now...
- Useful Links
My github: https://github.com/joaovsa7
LinkedIn: https://linkedin.com/in/jvsa7
Top comments (3)
Hi friend! If you're dockerizing Node.js apps to production you probably want to give this article a skim, as I'm seeing a bunch of stuff with your Dockerfile that could be improved: base image, not using an init system, not using a lower privileged user on the container, etc.
Great tips! Thank you my friend
You were copying your entire node_modules directory before