-
-
Notifications
You must be signed in to change notification settings - Fork 222
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
Optimize docker image size #91
Conversation
Dockerfile
Outdated
COPY ./package.json \ | ||
./package-lock.json \ | ||
./next.config.js \ | ||
./next-env.d.ts \ |
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.
This file does not exist as far as I can tell? So my test build of your branch is failing
Maybe I'm missing something
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.
I tried creating an empty file with the name just to get further, and it seems like it's gitignored, so I guess this is some sort of local file that I don't have (and which would not be present should a GHA be introduced to build images automatically or similar).
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.
Good catch, that seems like a generated file. I'll remove that line 👍
I like most of the changes (except that I'm not all that sold on the compression parts, but this feels very subjective)! If my changes or something similar could be incorporated in this PR, that PR could be closed down in favour of these changes. You probably have a better understanding of what the best practices around those things than I do, so if there is another solution that brings about the same result I would be equally good with that. Currently have tried building this branch locally with a completely empty |
Thanks for the review. I think I'll drop the compression stuff for now, I can later open a new PR for them specifically so that the other changes are not blocked. I'll take a look at #73 and check if there's an elegant solution that could be implemented on top of this PR. |
@justcallmelarry I made some changes:
With these changes, the three environment variables The fix works by directly reading the Note: the zod validations for these environment variables work, but seem to only trigger when accessing the app, not when starting up the container. |
@jantuomi nice 👍 I am sure that just having the PUBLIC_* env var set during build works, since that's how I'm running my own instance (set to false at build, then changed via container.env at runtime), and I'm not really great at next/ts in general, so I won't comment on that fix overall. I do think that the docker changes are great, and was trying to reach a similar result myself, but the aforementioned lack of knowledge of next made it a huge trial-and-error-process that did not bear fruit. if Sebastien thinks the ts-parts looks good, I can at least vouch for the docker-related parts |
I found a part of the reason for our confusion: in the expression Can you try manually specifying A common pattern regarding env vars is to parse the strings to a proper data object, similar to what is going on in the |
ah, that makes sense, i have |
The string/bool coercion issue is present in the env Zod validations as well. I added some preprocessing to those env vars so that they are validated correctly. I used the parsed Zod object to provide the runtime env. We have to wrap the reference to
With these changes, the env vars seem to work. |
hmm, I might misunderstand how this works, but now it kinda looks like all of the env vars are exposed to the frontend code? |
I think you understand correctly 😅 we obviously need to only allow the NEXT_PUBLIC_* vars through. Allowing everything would be pretty bad |
That's why I thought the previous solution looked nice from my perspective 😄 |
987ace9
to
8bb08bd
Compare
Alright, I brought back the feature flags object, this time using the Zod object behind the scenes 👍 |
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.
Amazing! Thanks @jantuomi and @justcallmelarry for this ❤️
You’ll just need to format the changes with Prettier (npx prettier -w src
) to make the pipeline pass :)
- Optimize docker image size
Co-authored-by: Sebastien Castiel <sebastien@castiel.me>
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.
amaze! 💯
With the latest changes I think this is ready for merging 👍 |
Problem
The current Dockerfile works well but has some issues:
node:21-slim
COPY ./ ./
)package.json
A built image on linux/amd64 is around 1.2GB in size. This size can be reduced significantly.
Changes
This PR addresses each of the issues and reduces the image size from 1.2GB to a nice 200MB. Changes include:
node:21-alpine
for a smaller base imagePOSTGRES_*
env vars in the Dockerfile itself so that the user does not have to remember to supply themprisma
from dev dependencies to actual dependencies inpackage.json
The multi-stage build is set up like so:
base
stagenpm run build
runtime-deps
stagebase
runner
stageruntime-deps
The compression/decompression steps contribute an around 200MB size reduction, using the compression algorithm
zstd
, which is a great balance of size reduction and processing speed. However, they cause a couple seconds of processing time both at compression time (during build) and at decompression time (during first container startup). This is time that is saved in disk and network I/O.Whether or not to include the compression/decompression may be controversial and can be removed if it is not seen as a good fit. I personally think it is a good thing to include.