Search code examples
linuxbashdockerstdin

Adding interactive user input e.g., `read` in a Docker container


I want to make a Docker image that can perform the following:

  1. Get user input and store it in a local variable using read
  2. Utilize that variable for a later command

Using that I have the following Dockerfile:

FROM ubuntu
RUN ["echo", "'Input something: '"]
RUN ["read", "some_var"]
RUN ["echo", "You wrote $some_var!"]

which, when running docker build, yields the following output:

Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM ubuntu
 ---> 4e2eef94cd6b
Step 2/4 : RUN ["echo", "'Input something: '"]
 ---> Using cache
 ---> a9d967721ade
Step 3/4 : RUN ["read", "some_var"]
 ---> Running in e1c603e2d376
OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"read\": executable file not found in $PATH": unknown

read seems to be a built-in bash "function" since which read yields nothing. I replaced ["read", "some_var"] with ["/bin/bash -c read", "some_var"] and ["/bin/bash", "-c", "read", "some_var"] but both yield the following:

...
Step 3/4 : RUN ["/bin/bash -c read", "some_var"]
 ---> Running in 6036267781a4
OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash -c read\": stat /bin/bash -c read: no such file or directory": unknown
...
Step 3/4 : RUN ["/bin/bash", "-c", "read", "some_var"]
 ---> Running in 947dda3a9a6c
The command '/bin/bash -c read some_var' returned a non-zero code: 1

In addition, I also replaced it with RUN read some_var but which yields the following:

...
Step 3/4 : RUN read some_var
 ---> Running in de0444c67386
The command '/bin/sh -c read some_var' returned a non-zero code: 1

Can anyone help me with this?


Solution

  • One solution is to use an external shell script and use ENTRYPOINT.

    Contents of run.sh:

    #!/bin/bash
    echo "Input something!"
    read some_var
    echo "You wrote ${some_var}!"
    

    Contents of Dockerfile:

    FROM ubuntu
    COPY "run.sh" .
    RUN ["chmod", "+x", "./run.sh"]
    ENTRYPOINT [ "./run.sh" ]
    

    This will allow ./run.sh to run when the container is spun:

    $ docker build -t test .
    Step 1/4 : FROM ubuntu
     ---> 4e2eef94cd6b
    Step 2/4 : COPY "run.sh" .
     ---> 37225979730d
    Step 3/4 : RUN ["chmod", "+x", "./run.sh"]
     ---> Running in 5f20ded00739
    Removing intermediate container 5f20ded00739
     ---> 41174edb932c
    Step 4/4 : ENTRYPOINT [ "./run.sh" ]
     ---> Running in bed7717c1242
    Removing intermediate container bed7717c1242
     ---> 554da7be7972
    Successfully built 554da7be7972
    Successfully tagged test:latest
    
    $ docker run -it test
    Input something!
    Test message 
    You wrote Test message!