Skip to content
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

Docker image is heavy #512

Open
Tom-Hudson opened this issue Feb 18, 2025 · 14 comments · May be fixed by #522
Open

Docker image is heavy #512

Tom-Hudson opened this issue Feb 18, 2025 · 14 comments · May be fixed by #522
Assignees
Labels
enhancement New feature or request optimize

Comments

@Tom-Hudson
Copy link
Contributor

Tom-Hudson commented Feb 18, 2025

The docker image weighs in at a hefty 769MB and it would be great if this could be reduced!

Image

I haven't dug too deep into the layers but there is a load of superfluous files such as *.txt, *.md *_test.go. However, this needs some time dedicated to it to do a proper job of it 😄

It does appear that best practice is already being used in the Dockerfile with the multi-stage builder pattern, minimal layers and using --no-cache for package installs but I am sure more can be done.

@rez1dent3 rez1dent3 self-assigned this Feb 18, 2025
@rez1dent3
Copy link
Member

@Tom-Hudson Hello. Thanks for the feedback.
I now it and I reduced image in 3.x version, but only ~ -8%.

I can shrink the image by another 15%, but then the application starts up much slower as it starts downloading dependencies. At the moment, I can't shrink the image without losing performance.

@Tom-Hudson
Copy link
Contributor Author

8% is still decent. I did check all the obvious avenues for optimising the size and came up with nothing you haven't already done!

I don't think a slower start is worth it! The image is cached once it's been pulled which is better than downloading dependencies every time you run it.

I am unsure if anything could be done with https://github.com/slimtoolkit/slim. I've used it with other images and it's worked a charm. It would require some fiddling with config to get it actually working though.

@rez1dent3
Copy link
Member

Thanks for the info. I'll check it out.
Yes, I don't have any ideas for optimization without losing startup speed. I won't close the issue for now, maybe someone will have an idea.

@Tom-Hudson
Copy link
Contributor Author

So I just had a play with slim and with the following command I was able to get a fully working image down to 303MB (~ -60%):
Image

Here is the command I used slim build --http-probe-cmd /api/health/readiness --http-probe-ports 4771 --mount ./stubs:/stub ${IMAGE}

However, this was on an image we create using the gripmock image as a base which we then preload the protos needed and override the CMD to start up the mock server. However, this same thing could be done to the gripmock image but you would need mount a proto path and pass in a proto (e.g. /proto/hello.proto) to the --cmd param. If I get some time I will create a PR to see what you think, but thought I would share ahead of this incase I don't get time...

@Tom-Hudson
Copy link
Contributor Author

Tom-Hudson commented Feb 19, 2025

@rez1dent3 okay I jumped the gun, so it was not fully working after more thorough testing. However, if I preserved the /usr/local/go/src/ path then it is working, although now it weighs in at 400MB still (~ -48%)

Image

Here is the updated command I used slim build --preserve-path /usr/local/go/src/ --http-probe-cmd /api/health/readiness --http-probe-ports 4771 --mount ./stubs:/stub ${IMAGE}

The issue was that it scrapped a go file that was needed.

@rez1dent3
Copy link
Member

@Tom-Hudson Got it and started testing, but this solution breaks wkt* and seriously spoils the startup speed. And also in the third version of cli healthcheck, which is more productive and it is extremely difficult to use in slim.

I will postpone the attempt at optimization for now.

@rez1dent3 rez1dent3 added enhancement New feature or request optimize labels Mar 10, 2025
@Tom-Hudson
Copy link
Contributor Author

@Tom-Hudson Got it and started testing, but this solution breaks wkt* and seriously spoils the startup speed. And also in the third version of cli healthcheck, which is more productive and it is extremely difficult to use in slim.

I will postpone the attempt at optimization for now.

That's a shame. I've not noticed a startup speed hit, but I'm using v2, so maybe that's why? I've also not noticed any problems with wkt, but then again that will be proto specific I guess. There is always the option to add another path for preservation.

Any optimisation is great and people still have the option of using slim themselves anyway. Although I'm going to do some startup time testing to see if we've had a drop in performance

@rez1dent3
Copy link
Member

I tested on these integration versions in v3, as there will be a release in the coming days.

Performance drops by ±18%. Many tests also drop and there is no way (or maybe I didn't find it) to do healthcheck via CLI.

@Tom-Hudson
Copy link
Contributor Author

I tested on these integration versions in v3, as there will be a release in the coming days.

Performance drops by ±18%. Many tests also drop and there is no way (or maybe I didn't find it) to do healthcheck via CLI.

Oh wow, we have not noticed a drop in performance at all as we are using these images in docker compose stacks and even with the default healthcheck interval of 30s (maybe consider increasing the interval? 👀), they aren't the slowest things to start up, so reducing the size of the images when being pulled made things faster for us. Any idea why the performance would have suffered? Is there some kind of cache that is being removed?

there is no way (or maybe I didn't find it) to do healthcheck via CLI.

Not sure what you meant by this, is this not what you mean? --http-probe-cmd /api/health/readiness

I am surprised some of the tests fail but I can imagine there will be some paths that need adding to --preserve-path. For us, we may not be using some of the things which are causing issues for you 🤷

Great news on the v3 release, excited to see this land 🚀

@rez1dent3
Copy link
Member

Any idea why the performance would have suffered? Is there some kind of cache that is being removed?

Yes, there are ideas, most likely some files are deleted and now they are collected every time at startup. This can be solved, but I will put it off for later. Right now it is not the most important thing for me.

Not sure what you meant by this, is this not what you mean? --http-probe-cmd /api/health/readiness

I need an analogue of the CMD check HEALTHCHECK CMD gripmock check --silent. It is also possible to check using http, but I would like to move some of the checks to the gripmock side.

I am surprised some of the tests fail but I can imagine there will be some paths that need adding to --preserve-path. For us, we may not be using some of the things which are causing issues for you 🤷

Yes, you are right. There is simply not enough time for all this now. I will definitely return to the slim version a little later.

@rez1dent3
Copy link
Member

In general, I looked at the slim report and most of the problems are in the optimization of the startup speed. If you remove this, the image will be greatly reduced. But I can't do this, I need to carefully go through the entire folder and separate the necessary files from the unnecessary ones.

        {
          "type": "RUN",
          "time": "2025-03-10T22:08:26Z",
          "is_nop": false,
          "local_image_exists": false,
          "layer_index": 14,
          "layer_id": "9618315a9494fbd61cf980998bba0ff1e8912224cee959b108d303ae8d62a96c",
          "layer_fsdiff_id": "sha256:9618315a9494fbd61cf980998bba0ff1e8912224cee959b108d303ae8d62a96c",
          "size": 358031647,
          "size_human": "358 MB",
          "command_snippet": "RUN go build -o /dev/null .",
          "command_all": "RUN go build -o /dev/null .",
          "system_commands": [
            "go build -o /dev/null ."
          ],
          "comment": "buildkit.dockerfile.v0",
          "is_buildkit_instruction": true,
          "inst_set_time_bucket": "2025-03-11T01:00:00+03:00",
          "inst_set_time_index": 3,
          "inst_set_time_reverse_index": 0
        },

@rez1dent3
Copy link
Member

For history:

  • /root/.cache/go-build
  • $GOPATH/pkg/mod

@Tom-Hudson
Copy link
Contributor Author

In general, I looked at the slim report and most of the problems are in the optimization of the startup speed. If you remove this, the image will be greatly reduced. But I can't do this, I need to carefully go through the entire folder and separate the necessary files from the unnecessary ones.

        {
          "type": "RUN",
          "time": "2025-03-10T22:08:26Z",
          "is_nop": false,
          "local_image_exists": false,
          "layer_index": 14,
          "layer_id": "9618315a9494fbd61cf980998bba0ff1e8912224cee959b108d303ae8d62a96c",
          "layer_fsdiff_id": "sha256:9618315a9494fbd61cf980998bba0ff1e8912224cee959b108d303ae8d62a96c",
          "size": 358031647,
          "size_human": "358 MB",
          "command_snippet": "RUN go build -o /dev/null .",
          "command_all": "RUN go build -o /dev/null .",
          "system_commands": [
            "go build -o /dev/null ."
          ],
          "comment": "buildkit.dockerfile.v0",
          "is_buildkit_instruction": true,
          "inst_set_time_bucket": "2025-03-11T01:00:00+03:00",
          "inst_set_time_index": 3,
          "inst_set_time_reverse_index": 0
        },

Nice, sounds like you're getting to the bottom of it.

@rez1dent3
Copy link
Member

Yes, I already knew that. That's why I looked there right away. If you remove that, gripmock will download dependencies every time you build a server and take a long time to build the server.

But maybe I'll make a slim version that will be slower than the main version and users will have a choice: performance or a small image size.

Thanks for the feedback.

@rez1dent3 rez1dent3 linked a pull request Mar 11, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request optimize
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants