Replies: 3 comments 1 reply
-
I think we should adopt strategy 1 (bash -C our buildpacks) as a short term solution while socializing and exploring strategy 2 (changing upstream behavior). |
Beta Was this translation helpful? Give feedback.
-
This recently came up in: |
Beta Was this translation helpful? Give feedback.
-
This would be great! Just stumbled on this using the ruby buildpack when it said it couldn't find ruby. I was attempting to run
I realized I could probably utilize the existing entrypoint process which worked but it's definitely not intuitive.
|
Beta Was this translation helpful? Give feedback.
-
Expected
When I build an image with a CNB then
docker run ... bash
that I will get an interactive shell to the imageActual
Example, if you follow this part of the tutorial https://github.com/heroku/buildpacks/blob/71afce6c7a4df02ff3d48830dc1c1fa8f574ccf7/TUTORIAL.md#configuring-multiple-languages but delete the procfile buildpack, and then try to run
docker run -it --rm my-python-nodejs-image bash
it will boot a webserver instead of giving you an interactive session.Analysis
(paraphrasing) The behavior of the CNB spec says that the values passed to the container will be passed to the
docker run
instance will be added as arguments to the default command. So if the default command isnpm run start
then callingdocker run ... bash
will effectively callnpm run start bash
which is not what we want.The reason the procfile buildpack doesn't have this problem is because it uses
bash -C
as the command and then passes in the rest as arguments. https://github.com/heroku/buildpacks-procfile/blob/58ca67cc03b78009fb821f26d2b8c39b55659478/src/launch.rs#L19 so that means if you givedocker run
the argbash
it will runbash -C bash
which does what we expectWorkarounds
The app user can workaround this issue by manually invoking the launcher as the
--entrypoint
, but this requires the end user to have knowledge of how the launcher works, and why this is needed. When the system does not behave as the user would expect, there is no hint for the application developer to look towards using the--entrypoint
flag in docker.Into the future
This would be improved by "system buildpacks" as described in this RFC https://github.com/buildpacks/rfcs/blob/ce8991b3d739f763b8356ae8696ae582f18c4af6/text/0101-system-buildpacks-in-builder.md?plain=1#L3 however this is accepted and not yet implemented. This would allow the builder to declare that the Procfile buildpack should always execute after any build made with the builder.
However, there will still be edge cases, for example, when someone does not have a Procfile in the root of their application.
Strategy 1 -
bash -C
all the thingsAll Heroku buildpacks could adopt the same
bash -C
strategy that the Procfile buildpack uses. We could recommend this strategy in documentation as well.Strategy 2 - Change the default behavior upstream
The default behavior of
docker run
is to run the default command and pass any arguments todocker run
to that default command instead of replacing it. We could try to be clever and optionally replace the command based on what's being passed in. Alternatively we could remove this "run default command" behavior so the user would be forced to rundocker run ... web
if they want to boot the web process. Or we could change it so thatdocker run
with no arguments runs the default command and any arguments are expected to be a full command replacement, rather than only arguments to that command.Beta Was this translation helpful? Give feedback.
All reactions