-
Notifications
You must be signed in to change notification settings - Fork 54
chore: reduce the docker image by 210 MB / 30% #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
🎉 Snyk checks have passed. No issues have been found so far.✅ security/snyk check is complete. No issues have been found. (View Details) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Summary
This PR implements a significant Docker image optimization that reduces the image size from 676MB to 466MB (30% reduction) by introducing esbuild bundling. The changes implement a sophisticated multi-stage build process that bundles the Node.js application code into single files and dramatically reduces the node_modules directory from 426MB to 101MB.
The optimization works through several key mechanisms:
-
Code Bundling: A new
esbuild.config.mjsconfiguration bundles multiple entry points (main API server, CLI, processors, and scheduler) into single executable files, leveraging tree-shaking to eliminate unused code -
Minimal Production Dependencies: Creates a streamlined production
node_modulescontaining only essential runtime dependencies that cannot be bundled (@bull-board/ui,@prisma/client,class-transformer,class-validator,prisma,zod) -
Prisma Optimization: Implements architecture-specific cleanup of Prisma engine binaries to remove unused platform-specific shared libraries
-
Multi-stage Docker Build: Modifies the Dockerfile to leverage the bundling process while maintaining the same runtime environment
The changes also include a minor code cleanup in render-templates.service.ts that removes a duplicate 'SINGBOX' case from a switch statement, keeping the version that dynamically parses client versions rather than using a hardcoded version.
This optimization strategy is particularly effective for Node.js applications with heavy dependency trees where only a fraction of the installed packages are actually used at runtime. The approach maintains the existing application architecture while significantly improving deployment efficiency through reduced image size.
Confidence score: 2/5
- This PR has significant potential for runtime failures due to the complexity of bundling a NestJS application with decorators, dynamic imports, and Prisma integration
- Score reflects high risk from bundling breaking NestJS's reflection-based dependency injection, potential Prisma client generation issues, and complex build process dependencies
- Pay close attention to the Dockerfile changes, esbuild configuration, and package.json dependency modifications as these could cause deployment failures
4 files reviewed, 2 comments
| '@nestjs/sequelize/dist/common/sequelize.utils', | ||
| '@nestjs/typeorm/dist/common/typeorm.utils', | ||
| '@nestjs/websockets/socket-module', | ||
| '@remnawave/*', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: external pattern '@remnawave/*' may not work correctly with current local library structure - consider being more specific
|
Not sure about bundling all things into one .js file... nestjs/nest#1706 (comment) |
|
Yes, the mongoose example is handled within esbuild.config.mjs. Backend is starting up and working fine; node as well; it is a significant image size reduction that doesn't need any maintenance with all of the logic being contained in a single file. I think things have changed since 2020, lots of references to bundling: |
|
What is compressed size? |
|
61MB / 29% smaller: |
Shrink the docker image by 210MB, by using esbuild to bundle the code into single file (the executables have duplicates now, need to switch the local modules to ESM to be able to use them and reduce this, but due to duplication the resulting build is only 5MB larger than current).
Result:
The bundled code results in:
The savings mostly come from reduced node_modules, by not including the code that is not executed; and avoiding shipping of entire
node_modules, but keeping the minimals that do not bundle:Also removing of duplicated prisma client libs that are not relevant:
One of these is a symlink:
Hosts view doesn't work, but this is probably from dev branch: