How to update Docker container PATH using commit “

2019-07-16 04:36发布

问题:

I've been trying to update container PATH env variable value using docker commit --change ... flag but I must be lacking understanding of some part involved as I'm unable to get desired result.

Given:

$ docker run -it centos:6 /bin/bash
[root@3b459018aa84 /]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
exit

Attempt 1:

$ docker commit -c "ENV PATH /usr/local/texlive/bin:${PATH}" 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
[root@25116cd93d79 /]# echo $PATH
/usr/local/texlive/bin:/opt/local/bin:/opt/local/sbin:/Users/Ivan/.jenv/shims:/Users/Ivan/.jenv/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/share/dotnet:/opt/X11/bin

Resulting PATH seems to contain host machine's PATH value. I'm guessing it is because I used double quotes which caused ${PATH} to be expanded before being passed to docker commit.

Attempt 2:

$ docker commit -c 'ENV PATH /usr/local/texlive/bin:${PATH}' 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
[root@c10a98a7fbce /]# echo $PATH
/usr/local/texlive/bin:

Attempt 3:

$ docker commit -c "ENV PATH=\"/usr/local/texlive/bin:${PATH}\"" 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
[root@240c3e268d08 /]# echo $PATH
/usr/local/texlive/bin:/opt/local/bin:/opt/local/sbin:/Users/Ivan/.jenv/shims:/Users/Ivan/.jenv/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/share/dotnet:/opt/X11/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands

Attempt 4:

$ docker commit -c 'ENV PATH=\"/usr/local/texlive/bin:${PATH}\"' 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
[root@bb10d27f1360 /]# echo $PATH
"/usr/local/texlive/bin:"

Attempt 5:

$ docker commit -c 'ENV PATH="/usr/local/texlive/bin:${PATH}"' 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
[root@a683ab06f4d3 /]# echo $PATH
/usr/local/texlive/bin:

Attempt 6:

After reading docker commit documentation one more time I saw --pause flag. And so I tested a theory that pausing container affects access to the environment variables during commit.

$ docker commit -c 'ENV PATH="/usr/local/texlive/bin:${PATH}"' -p=false 3b459018aa84 test-changes
$ docker run -it test-changes /bin/bash
/usr/local/texlive/bin:

Nope, no luck either...

Desired output:

[root@c10a98a7fbce /]# echo $PATH
/usr/local/texlive/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

In other words I want the output to be as if ENV PATH /usr/local/texlive/bin:${PATH} was added to Dockerfile.

I'm guessing I'm missing something silly and hopefully obvious to others but I'm out of ideas.

In case it comes to that, I'm running on Mac OS 10.13.2, Docker 17.12.0-ce-mac55 (23011).

回答1:

1st step: accessing the $PATH variable of the container

You can do this with inspect:

docker container inspect container_name --format '{{ index .Config.Env 0 }}'

2nd step: append something to $PATH and commit to a new image

I will place the command from previous step inside `` (backticks),

docker container commit -c "ENV `docker container inspect container_name --format '{{ index .Config.Env 0 }}':some_other_path_goes_here`" container_name new_image_name

Visit the following question to see how it works:

What does ` (backquote/backtick) mean in commands?

Everything you type between backticks is evaluated (executed) by the shell before the main command and the output of that execution is used by that command, just as if you'd type that output at that place in the command line.

Example

  1. run a new container and echo its $PATH variable:

    $ docker container run --rm -itd --name my_container ubuntu
    25b357a26d68f047dd98c87ff4598800db160ad3136470f3285ccd20c1297cfa
    
    $ docker container exec -it my_container /bin/sh -c 'echo $PATH'
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
  2. commit to a new image by appending something to the old $PATH value (notice that the container wasn't stopped or paused):

    $ docker container commit -c "ENV `docker container inspect my_container --format '{{ index .Config.Env 0 }}':some_other_path_goes_here`" my_container new_image_name
    sha256:584226328c3da8b6239ec8f8b92f71ce2e03090341c6efb03602055fbf1ff582
    
  3. run a new container based on that image and echo its $PATH variable:

    $ docker container run --rm -itd --name my_new_container new_image_name
    40279673d0c45de7ab53d6be488d6ff32259e3bc8a76bd2ef41a53f065a2ba30
    
    $ docker container exec -it my_new_container /bin/sh -c 'echo $PATH'
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:some_other_path_goes_here
    


回答2:

In this particular scenario best option for me was to upgrade to Docker Edge version (18.02 at the time of writing) since it was a bug in Moby Project that was causing difference between using Dockerfile and --change flag on commit.



标签: docker