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

suggestion: remove ENTRYPOINT from distroless images [8.0] #4650

Closed
tmds opened this issue Jun 5, 2023 · 13 comments
Closed

suggestion: remove ENTRYPOINT from distroless images [8.0] #4650

tmds opened this issue Jun 5, 2023 · 13 comments

Comments

@tmds
Copy link
Member

tmds commented Jun 5, 2023

Distroless images set :

ENTRYPOINT ["/usr/bin/dotnet"]
CMD ["--info"]

and non-distroless images do not.

FROM base
...
CMD ["/usr/bin/dotnet", "assembly.dll" ]

If you switch base for the above Dockerfile from a regular to a distroless, the distroless application image won't work because the ENTRYPOINT is pre-pended to the command. It tries to execute: /usr/bin/dotnet /usr/bin/dotnet assembly.dll.

@mthalman what do you think about removing the ENTRYPOINT from the distroless images? Is there a strong reason to set this?

If desired, CMD can still be set to CMD ["/usr/bin/dotnet", "--info" ].

This also applies the Ubuntu Chiseled images: https://github.com/ubuntu-rocks/dotnet.

I noticed the difference while working on: dotnet/sdk-container-builds#398.

cc @baronfel

@mthalman
Copy link
Member

mthalman commented Jun 5, 2023

This was the issue that prompted this change and explains the reasoning: #3866

@tmds
Copy link
Member Author

tmds commented Jun 5, 2023

There is no real use-case mentioned in that issue.

These images are meant to be used as base images, and setting an ENTRYPOINT affects how derived images behave for CMD.

The suggestion is to change:

 ENTRYPOINT ["/usr/bin/dotnet"] 
 CMD ["--info"] 

to

 CMD ["/usr/bin/dotnet", "--info"] 

Then CMD in derived images works the same across regular and distroless base images.

What do you think?

@mthalman
Copy link
Member

mthalman commented Jun 5, 2023

Then CMD in derived images works the same across regular and distroless base images.

What is the use case for using CMD in regular images without also using ENTRYPOINT? I'm trying to better understand where the friction point is for switching between the image types. Can you provide a concrete example of what makes it problematic today?

@jander-msft
Copy link
Member

For derived images with framework-dependent apps, would it not be easier for those developers to just specify:

CMD ["/app/MyApp.dll"] 

without having to understand where the .NET runtime is installed?

@tmds
Copy link
Member Author

tmds commented Jun 5, 2023

What is the use case for using CMD in regular images without also using ENTRYPOINT? I'm trying to better understand where the friction point is for switching between the image types. Can you provide a concrete example of what makes it problematic today?

An ENTRYPOINT is sometimes used to wrap the CMD and perform initialization.

I'm adding support to the sdk tooling to work well with Red Hat base images (dotnet/sdk-container-builds#397) which use this pattern.

Currently, the thinking is we can make the tooling emit a CMD when the base image already defines an ENTRYPOINT (dotnet/sdk-container-builds#398, dotnet/sdk#33037).

While trying some things I noticed the distroless images have an ENTRYPOINT defined.

I don't think we gain something with this ENTRYPOINT and its drawback is that it makes CMD mean different things depending on the base image used.

For derived images with framework-dependent apps, would it not be easier for those developers to just specify:

That doesn't work the same accross distroless and regular images. It also doesn't work when invoking the app through the apphost.

@mthalman
Copy link
Member

mthalman commented Jun 5, 2023

its drawback is that it makes CMD mean different things depending on the base image used.

My view is that using CMD without also specifying ENTRYPOINT is not a good practice. It places too much dependency on how the base image is defined, exactly what you're seeing here. In our sample Dockerfiles, we illustrate the recommended approach of setting the ENTRYPOINT in your app's Dockerfile: https://github.com/dotnet/dotnet-docker/blob/948b5fd2b9a77a783b80f712cfc6cc2375665b49/samples/dotnetapp/Dockerfile#LL19C1-L19C39. If you do that, it will work properly with either base image type.

Note that the reason for #3866 was not intended to be a convenience to users that would allow them to use CMD. Rather, it was to simply make the container's default implementation have some reasonable behavior rather than just an error when running it.

@tmds
Copy link
Member Author

tmds commented Jun 5, 2023

My view is that using CMD without also specifying ENTRYPOINT is not a good practice. It places too much dependency on how the base image is defined, exactly what you're seeing here. In our sample Dockerfiles, we illustrate the recommended approach of setting the ENTRYPOINT in your app's Dockerfile: https://github.com/dotnet/dotnet-docker/blob/948b5fd2b9a77a783b80f712cfc6cc2375665b49/samples/dotnetapp/Dockerfile#LL19C1-L19C39. If you do that, it will work properly with either base image type.

I understand what you recommend.

Can you explain why

 ENTRYPOINT ["/usr/bin/dotnet"] 
 CMD ["--info"] 

is preferable to

 CMD ["/usr/bin/dotnet", "--info"] 

?

If there is no reason, CMD can mean the same thing for distroless base images and regular base images if we change to the latter.

@mthalman
Copy link
Member

mthalman commented Jun 5, 2023

Can you explain why

 ENTRYPOINT ["/usr/bin/dotnet"] 
 CMD ["--info"] 

is preferable to

 CMD ["/usr/bin/dotnet", "--info"] 

?

If there is no reason, CMD can mean the same thing for distroless base images and regular base images if we change to the latter.

  1. It's more intuitive. By default, there's no entrypoint so, intuitively, it makes more sense to set one and use CMD for the args. We then might need to respond to questions of why we did it this way since it seems outside the norm.
  2. Setting ENTRYPOINT is also self-documenting in the image metadata for the Config.Entrypoint property which helps describe the intent of the image we produce.
  3. It'd also be a breaking change that we'd need to document if we changed it at this point. If we're going to do that, I'd want the reason for doing so to be a compelling one.

@tmds
Copy link
Member Author

tmds commented Jun 5, 2023

It's more intuitive. By default, there's no entrypoint so, intuitively, it makes more sense to set one and use CMD for the args. We then might need to respond to questions of why we did it this way since it seems outside the norm.

Setting ENTRYPOINT is also self-documenting in the image metadata for the Config.Entrypoint property which helps describe the intent of the image we produce.

I don't find this intuitive, or self-documenting.

This following message means: "bash is not found".

~$ podman run mcr.microsoft.com/dotnet/nightly/aspnet:8.0.0-preview.5-jammy-chiseled-amd64 bash
The command could not be loaded, possibly because:
  * You intended to execute a .NET application:
      The application 'bash' does not exist.
  * You intended to execute a .NET SDK command:
      No .NET SDKs were found.

Download a .NET SDK:
https://aka.ms/dotnet/download

Learn about SDK resolution:
https://aka.ms/dotnet/sdk-not-found

It'd also be a breaking change that we'd need to document if we changed it at this point. If we're going to do that, I'd want the reason for doing so to be a compelling one.

Except for the 7.0 Mariner image, this seems to be new for 8.0.

The main reason is to make CMD mean the same thing for distroless and regular images.

@mthalman
Copy link
Member

mthalman commented Jun 5, 2023

The main reason is to make CMD mean the same thing for distroless and regular images.

But why are you using CMD in this way? Here's a snippet from Docker's documentation for ENTRYPOINT:

You can use the exec form of ENTRYPOINT to set fairly stable default commands and arguments and then use either form of CMD to set additional defaults that are more likely to be changed.

Why do you want to use CMD in this way to include dotnet when ENTRYPOINT solves the issue?

@tmds
Copy link
Member Author

tmds commented Jun 5, 2023

But why are you using CMD in this way?

The use-case that triggered me is to use a helper script ENTRYPOINT (as described in https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#entrypoint) in combination with a CMD that starts the .NET app.

That made me look if some dotnet/dotnet-docker base images set the ENTRYPOINT, which I learned to be the case for the distroless images.

This ENTRYPOINT isn't such a helper script.

I don't see the advantage it gives.
And it gets in the way of CMD working the same way as it does for the regular (non-distroless) base images.

@mthalman
Copy link
Member

mthalman commented Jun 6, 2023

And it gets in the way of CMD working the same way as it does for the regular (non-distroless) base images.

It doesn't get in the way if you use ENTRYPOINT, which is the recommended way of doing things in this case. The best practice is for ENTRYPOINT to target the primary executable of the container. And CMD can be used to further provide default, overridable options of that executable.

@tmds
Copy link
Member Author

tmds commented Jun 6, 2023

It would be nice if the base image wasn't opinionated and would allow both CMD and ENTRYPOINT to be usable.

It seems you disagree, so I'll close this suggestion.

@tmds tmds closed this as completed Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

3 participants