'`docker build` hangs based on order of install

Given this Dockerfile:

FROM ubuntu:20.04

RUN set -ex && apt-get update

RUN set -ex && \
    apt-get install -y \
    git

RUN set -ex && \
    apt-get install -y \
    cmake

ENV HOME_DIR /home/develop

WORKDIR ${HOME_DIR}

The docker build hangs configuring tzdata:

$ DOCKER_BUILDKIT=0 docker build -f Docker/Dockerfile -t cmake:latest .
Sending build context to Docker daemon  161.8kB
Step 1/6 : FROM ubuntu:20.04
 ---> 7e0aa2d69a15
Step 2/6 : RUN set -ex && apt-get update
 ---> Using cache
 ---> 78e8a28063b0
Step 3/6 : RUN set -ex &&     apt-get install -y    git
 ---> Using cache
 ---> d400fc509ae8
Step 4/6 : RUN set -ex &&     apt-get install -y    cmake
 ---> Running in 2c58632e70a3
+ apt-get install -y cmake
Reading package lists...
Building dependency tree...
Reading state information...
...
Setting up tzdata (2021a-0ubuntu0.20.04) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
Configuring tzdata
------------------

Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.

  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
  2. America     5. Arctic     8. Europe    11. SystemV
  3. Antarctica  6. Asia       9. Indian    12. US
Geographic area: 

If I reverse the order of git and cmake it will successfully build. Why would order matter?

I'm running Docker 20.10.5 on MacOS 11 (Big Sur).



Solution 1:[1]

Suppress prompting from apt by setting the DEBIAN_FRONTEND variable, which can be done with a build arg that only exists during the build (allowing interactive users exec'd into a container):

FROM ubuntu:20.04

ARG DEBIAN_FRONTEND=noninteractive
RUN set -ex && \
    apt-get update && \
    apt-get install -y \
    git

RUN set -ex && \
    apt-get update && \
    apt-get install -y \
    cmake

ENV HOME_DIR /home/develop

WORKDIR ${HOME_DIR}

Also, note that the update should be run with the install step to avoid stale caches from breaking builds.

Solution 2:[2]

The CMake package must silently pick a default selection for tzdata before it is installed (as a dependency of git?). Odd, but the workaround is easy enough. Add the following lines near the top of your Dockerfile:

ENV TZ=America/Los_Angeles
RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime
RUN echo "$TZ" > /etc/timezone

RUN apt-get update
RUN apt-get install -y tzdata

Naturally, replace America/Los_Angeles with whichever timezone you believe is most appropriate for your application, maybe UTC.

Solution 3:[3]

Git installs perl as one of its dependencies, and that installs the Term::ReadLine perl module as well. With this module, when installing cmake, debconf can initialize the Readline frontend, and can wait for input. But if you install cmake first, this module doesn't exist yet locally, and debconf will fail to setup tzdata, and will use the default configuration.

The above is proven by the logs, if we install cmake first:

Setting up tzdata (2021a-0ubuntu0.20.04) ...
[243/1270]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 (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.30.0 /usr/local/share/perl/5.30.0 /usr/lib/x86_64-linux-gnu/perl5/5.30 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.30 /usr/share/perl/5.30 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.)
debconf: falling back to frontend: Teletype
Configuring tzdata
------------------
Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.
1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
2. America     5. Arctic     8. Europe    11. SystemV
3. Antarctica  6. Asia       9. Indian    12. US
Geographic area:
Use of uninitialized value $_[1] in join or string at /usr/share/perl5/Debconf/DbDriver/Stack.pm line 111.
Current default time zone: '/UTC'
Local time is now:      Sat May  8 21:19:41 UTC 2021.
Universal Time is now:  Sat May  8 21:19:41 UTC 2021.
Run 'dpkg-reconfigure tzdata' if you wish to change it.

Solution 4:[4]

On my MacOS Catalina version 10.15.7 and Docker version 19.03.13, build 4484c46d9d

I added this in my Dockerfile and it works well without hanging

RUN DEBIAN_FRONTEND="noninteractive" apt-get update && apt-get -y install tzdata

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BMitch
Solution 2 Alex Reinking
Solution 3 Andruida
Solution 4 Nasser Abdou