Background:
Stack's Docker support initializes the PATH in the container using the container's default PATH, taken apparently from docker inspect. That relies on the unenforced best practice of setting a reasonable PATH in the Dockerfile:
https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#/env
@dysinger just tried using stack on an image that doesn't follow this best practice (he said he generated the image via packer), and got trouble because default PATH entries like /usr/bin were not set.
Issues:
- If the PATH from
docker inspect is empty, there's no default value (not even the "/bin:/usr/bin" hinted by man 3 execvp on Linux). Adding a reasonable standard value from some better source would help a lot (and would have avoided his issue).
- This was tricky to debug because the docs were incomplete. This whole process to setup
PATH seems not described in the docs (https://docs.haskellstack.org/en/latest/docker_integration/), I had to rely on source code and comments. I'm not sure how much of this should be documented, but probably something should. For extra fun, running a shell in the container would usually show a reasonable PATH, set up by shell initialization, confusing debugging. For instance, this command showed a correct PATH:
docker run -i -t --rm $curr_image sh -c 'echo $PATH'
I wonder whether stack should fetch the PATH from this command instead of docker inspect: this would be less error-prone for users, but it could be a bad idea for some reason (I don't understand this code enough.
- IIUC, a value of
PATH specified manually in stack.yaml overrides anything setup above, including the extra folders added by Stack, which probably causes trouble.
To see whether PATH was initialized by the Dockerfile for some container/image $NAME, one can run docker inspect -f '{{.Config.Env}}' $NAME to get the predefined environment variables, and search PATH among them.
Relevant code:
|
newPathEnv <- augmentPath |
|
[ hostBinDirPath |
|
, sandboxHomeDir </> $(mkRelDir ".local/bin")] |
|
(T.pack <$> lookupImageEnv "PATH" imageEnvVars) |
(set up PATH);
|
-- | Parsed @Config@ section of @docker inspect@ output. |
|
data ImageConfig = ImageConfig |
|
{icEnv :: [String] |
|
,icEntrypoint :: [String]} |
|
deriving (Show) |
(comments on icEnv, from which
imageEnvVars comes).
Background:
Stack's Docker support initializes the PATH in the container using the container's default PATH, taken apparently from
docker inspect. That relies on the unenforced best practice of setting a reasonable PATH in the Dockerfile:https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#/env
@dysinger just tried using stack on an image that doesn't follow this best practice (he said he generated the image via
packer), and got trouble because default PATH entries like/usr/binwere not set.Issues:
docker inspectis empty, there's no default value (not even the "/bin:/usr/bin" hinted byman 3 execvpon Linux). Adding a reasonable standard value from some better source would help a lot (and would have avoided his issue).PATHseems not described in the docs (https://docs.haskellstack.org/en/latest/docker_integration/), I had to rely on source code and comments. I'm not sure how much of this should be documented, but probably something should. For extra fun, running a shell in the container would usually show a reasonable PATH, set up by shell initialization, confusing debugging. For instance, this command showed a correct PATH:docker run -i -t --rm $curr_image sh -c 'echo $PATH'I wonder whether stack should fetch the PATH from this command instead of
docker inspect: this would be less error-prone for users, but it could be a bad idea for some reason (I don't understand this code enough.PATHspecified manually instack.yamloverrides anything setup above, including the extra folders added by Stack, which probably causes trouble.To see whether
PATHwas initialized by the Dockerfile for some container/image$NAME, one can rundocker inspect -f '{{.Config.Env}}' $NAMEto get the predefined environment variables, and searchPATHamong them.Relevant code:
stack/src/Stack/Docker.hs
Lines 300 to 303 in 8aaef91
stack/src/Stack/Docker.hs
Lines 928 to 932 in 8aaef91
imageEnvVarscomes).