33

I'm trying to automate a creation of a development Docker image using docker build command with appropriate Dockerfile. One of the scripts that I need to run in a RUN command wants the user to click through and read their license agreement. Thus there are two questions:

  1. Where is the output of all the RUN commands in a Dockerfile?
  2. What solution is possible to interact with the aforementioned command? Right now the docker build command just gets stuck asking user for input in an infinite loop.
ilya1725
  • 4,496
  • 7
  • 43
  • 68

5 Answers5

24

You can also do it in several steps, begin with a Dockerfile with instructions until before the interactive part. Then

docker build -t image1 .

Now just

docker run -it --name image2 image1 /bin/bash

you have a shell inside, you can do your interactive commands, then do something like

docker commit image2 myuser/myimage:2.1

The doc for docker commit

https://docs.docker.com/engine/reference/commandline/commit/

you may need to specify a new CMD or ENTRYPOINT, as stated in the doc

Commit a container with new CMD and EXPOSE instructions

For example some docker images using wine do it in several steps, install wine, then launch and configure the software launched in wine, then docker commit

user2915097
  • 30,758
  • 6
  • 57
  • 59
15

The output of RUN commands is shown in your terminal during the build. The Docker build process is completely non-interactive, so you must find some way of either auto-accepting the terms (almost every piece of software allows this, think apt-get install -y...) or using some shell wizardry to echo the acceptance back to the process or whatever (Expect maybe?).

johnharris85
  • 17,264
  • 5
  • 48
  • 52
  • Yes, I do use `-y` for `apt-get` type of applications. But this one is some commercial thing. – ilya1725 Nov 28 '16 at 22:48
  • 3
    Yes, commercial things are usually really shitty ;) But I'd be surprised if they didn't have a non-interactive mode :) If not then look into Expect. – johnharris85 Nov 28 '16 at 23:32
  • 1
    I have similar issue. I am installing conda(arm based image is not available at present) in docker while building the image. Code looks like `RUN bash Anaconda3-2021.04-Linux-aarch64.sh` and that's where things go wrong because it requires entering multiple times yes. Any suggestion how it can be handled. – Vineet May 18 '21 at 12:04
  • Is there a link to how to use expect in the dockerfile? – Sidharth Ghoshal Jun 11 '21 at 17:08
4

You can use the technique here:

(echo "initial command" && cat) | some_tool

Or, if multiple stages use printf and concat with \n:

(printf "cmd1\ncmd2" && cat) | some_tool
nikojpapa
  • 660
  • 1
  • 8
  • 16
  • `(echo "passwword" && cat) | sudo ls ` doesn't work and I took sudo as a common example of an interactive tool. – Atomosk Jun 02 '20 at 04:58
  • @Atomosk Many console-based programs like `sudo` do not read sensitive data like passwords from stdin, but more directly from the terminal. You can use `-S` to make `sudo` read from stdin. – creativecoding Jun 18 '20 at 22:56
  • @creativecoding I know about -S, what is why I said that `sudo` is just an common example. Everyone can test and see that `echo` won't help you with that. – Atomosk Jun 20 '20 at 00:49
  • I tested it on APT and some some terms that needed to be accepted and it worked flawlessly. – samvv Apr 04 '23 at 18:12
1

To see output of all commands during build, if they are not showing up in enough detail for you, try:

docker build --progress=plain --no-cache -t yourTag .

Dmitri R117
  • 2,502
  • 23
  • 20
1

You could use a tool like expect to automate the user interaction.

  1. Add expect to your image (preferably a build step because you will not need it later). E.g.
RUN apt update && apt install -yq expect
  1. Create a script to run, something like:
#!/usr/bin/env expect
set timeout 10
spawn some_program_that_requires_interaction.sh
expect "Some string that we want to wait for"

# send newline, simulating pressing enter:
send -- "\r"
expect eof
  1. Copy the script into your image and run it:
COPY my_expect_script .
RUN sh my_expect_script

This is totally untested, and it's difficult to know how well it'll work with your specific scenario. Expect doesn't work so well when curses is involved (or any kind of CLI UI that plays around with cursor position), so your mileage may vary.

aidan
  • 9,310
  • 8
  • 68
  • 82