Always use smaller images such as alpine or slim rather than the usual base images.
Base image size: 1.0GB++
Alpine image size: ±250MB
FROM node:22-alpine
Or better, use distroless as it is not an OS and only a runtime environment for your application.
Distroless Github Link:
https://github.com/GoogleContainerTools/distroless
Put the most frequent changes on the end of the Dockerfile.
FROM node:22-alpine
WORKDIR /app
# Dependencies tends to change less than your code
# So it is executed first
COPY ./package*.json ./
RUN npm install
# Then you can copy your code
COPY . .
RUN npm run build
EXPOSE 4173
CMD ["npm", "run", "preview"]
Remove unnecessary context on your Dockerfile by utilizing .dockerignore on your project. Put it on the directory where your Dockerfile belongs.
# .dockerignore
# Node
node_modules # node_modules aren't necessary as you will build your app
npm-debug.log # which compile them as static files
dist
# Version Control
.git
.gitignore
# IDE and Editor files
.vscode
.idea
*.swp
*.swo
# GOOD TO HAVE AS YOUR ENV ISN'T SUPPOSE TO BE ON YOUR DOCKER IMAGE
# Environment files
.env
.env.local
.env.*
# Testing
coverage
*.test.js
# DS Files
.DB_Store
Then to further your image size, you can clean up your project such as: