在Docker安装过程中,是否有可能回答对话框问题?

105

在使用apt-get安装一些软件包时,是否有可能以对话框的形式回答所提出的问题?

例如,我正在尝试使用以下命令设置包含mail-stack-delivery软件包的容器:

FROM ubuntu

RUN apt-get install -y mail-stack-delivery

然而,当构建该dockerfile时,会产生数十个错误,例如:
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (Can't locate Term/ReadLine.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7, <> line 11.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin: 

据我所知,我无法简单地响应对话框,但是是否有一种方法可以事先传递参数以回答每个问题?我知道只需更改一些配置即可完成此操作,因此我可以在事后执行此操作,但假定最好让安装脚本执行此操作,以便设置所有内容。

8个回答

119
请参见此处的讨论:https://github.com/docker/docker/issues/4032。简而言之,不建议设置ENV DEBIAN_FRONTEND noninteractive,因为它会持久存在于最终镜像中,即使运行docker run -i -t ... bash等命令也是如此。因此,建议要么省略DEBIAN_FRONTEND并接受警告,要么为每个命令明确指定它,例如RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q package
幸运的是,新的ARG指令设置了仅在构建期间存在的变量,因此现在可以使用更优雅的解决方案,该方案在DockerFile中指定但不会持久存在于最终镜像中:ARG DEBIAN_FRONTEND=noninteractive

我曾经在构建 Dockerfile 时遇到一个 RUN apt-get -y -qq install python-pip php-mbstring php-bcmath 命令,它在提示信息中停止了构建,并显示了 A new version (/usr/lib/php/7.0/php.ini-production.cli) of configuration file /etc/php/7.0/cli/php.ini is available, but the version installed currently has been locally modified 的消息,询问了我关于修改后的配置文件 php.ini 的处理方法,即 1. 安装新版本,2. 保留本地版本。通过添加这个环境变量,省略了提示。 - Shadi

26

您应该将DEBIAN_FRONTEND=noninteractive设置为环境变量。在大多数情况下,这会使安装过程不出现错误。

另外,如@Azdle所提到的,使用debconf-set-selections可以让您设置特定的项目。


19

13

ENV DEBIAN_FRONTEND noninteractive对我无效

ARG DEBIAN_FRONTEND=noninteractive同样无效

但是RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections可以解决问题


1
这个有效!谢谢! - undefined

10
这是可行的解决方案:
ARG DEBIAN_FRONTEND=noninteractive

5
请问您能否解释您的答案?例如为什么这样做有效,问题出在哪里等。 - Leander Moesinger
1
当然。我也遇到了同样的问题。我尝试添加"RUN DEBIAN_FRONTEND=noninteractive apt-get install",但是收到了相同的错误。如果我将"RUN DEBIAN_FRONTEND=noninteractive"添加到所有apt-get命令中,那么它就可以正常工作了。之后,我添加了"ARG DEBIAN_FRONTEND=noninteractive",现在它像魔法一样运行!抱歉我的回答可能不太专业,我是新手。我可以删除它 :) - vovandos
1
一个好的答案不仅要解决问题,还要解释背后的原理。例如看一下被接受的答案。所以我建议你要么大幅编辑你的答案并包含一些关于这些命令为什么起作用的背景信息,要么就将其删除。我知道你的出发点是好的,但最终我们想要保持高水平。 - Leander Moesinger
1
踩一下。这个解决方案已经在一年前被提到在接受的答案的最后部分。 - questionto42

8

成功的例子:

echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
sudo apt-get install -y -q <package name>

2

添加小型软件包“dialog”也可以解决此问题。

&& sudo apt-get -y install dialog

1
ENV DEBIAN_FRONTEND=noninteractive(或传统语法的ENV DEBIAN_FRONTEND noninteractive)有时起作用,有时不起作用,这与sudo的使用有关。默认情况下,sudo忽略当前用户的环境并使用一个干净的环境。可以通过sudo --preserve-env标志来控制。显然,在每个sudo调用中添加这个标志很麻烦,但是通过将环境变量添加到操作系统的/etc/environment文件中,可以使整个系统对于每个用户都是非交互式的。请保留HTML标签。
RUN set -a \
 && eval "$(sudo tee --append /etc/environment <<<'DEBIAN_FRONTEND=noninteractive')" \
 && set +a \
 && sudo apt-get update \
 && sudo apt-get install mail-stack-delivery

快速解析重要的片段:

# export every variable that follows
set -a

# appends the given string to the `/etc/environment` file as root
# tee prints its input to standard out
# eval interprets the output of tee
eval "$(sudo tee --append /etc/environment <<<'DEBIAN_FRONTEND=noninteractive')"

# stop exporting everything
set +a

之前曾提到不应该以这种全局方式设置DEBIAN_FRONTEND=noninteractive。这取决于您的镜像意图是什么。如果是为了自动化而不是为了人类使用,那么以全局方式设置是完全可以的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接