213

When I try to

apt-get install -y tzdata

the command line option for picking timezone shows up. I am trying to use this in a script to do some setup, how can I make the apt-get run without user input?

I know to reconfigure the tzdata I can do

echo "America/New_York" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata

But when installing I need it to run fully even if it doesn't set the right timezone, I can always reconfigure it.

I tried

echo 5 | apt-get install -y tzdata

but it is not working as expected.

Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
PYA
  • 8,096
  • 3
  • 21
  • 38
  • https://stackoverflow.com/a/20693661/1174169, while marked as "off-topic" also answers this question, by creating a "pre-seed" text file with debconf settings, prior to running `apt-get install`. With this technique I was able to install tzdata non-interactively without any symlink workarounds. – cod3monk3y Jan 26 '22 at 23:53
  • UPDATE: just noticed the same answer from @freelance below, using debconf – cod3monk3y Jan 27 '22 at 00:00

8 Answers8

300

This is the script I used

(Updated Version with input from @elquimista from the comments)

#!/bin/bash

ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
dpkg-reconfigure --frontend noninteractive tzdata

Seems to work fine.

As one liner:

DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata
Stabledog
  • 3,110
  • 2
  • 32
  • 43
PYA
  • 8,096
  • 3
  • 21
  • 38
  • 74
    If you are fine with UTC, here's a one-liner: `DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata` – elquimista Sep 19 '18 at 11:12
  • 13
    This is such a pain. I can't install tzdata without it prompting me to set my default timezone (configuration prompt during package installation? whose idea was this?), and I can't set the default timezone without first installing tzdata. It already defaults to UTC if you pass in EOF. Why not just do that and let user update later if they want. Or let me set TZ environment variable and have tzdata look for that. – theferrit32 Apr 16 '19 at 23:16
  • 4
    Doing `ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime` step before `DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata` was the only way I could get this to install w/o a prompt. – fncomp Jun 14 '19 at 21:18
  • Same goes for me, the only way this worked was by placing the ln statement first. @PYA. – jpruiz114 Jun 16 '19 at 21:55
155

If someone wants to achieve it in Dockerfile, use as below.

RUN DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata
Stabledog
  • 3,110
  • 2
  • 32
  • 43
Youngjae
  • 24,352
  • 18
  • 113
  • 198
  • 26
    This can be done as a single line: ```RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ...``` The `DEBIAN_FRONTEND` variable must be set for the `install` part. It does not work if set before the `&&` for the `update` part. – Daniel Stevens Aug 24 '20 at 04:01
  • 1
    Issuing `ARG DEBIAN_FRONTEND=noninteractive` on a separate line worked for me _sometimes_, while on a single line as recommended by @DanielStevens worked for me _always._ – Stephan Samuel Feb 19 '21 at 02:32
  • 1
    `ARG` is useful for when you have command-line arguments. You want `ENV` to set it unconditionally. – tripleee Oct 28 '21 at 18:49
  • 1
    Setting `DEBIAN_FRONTEND=noninteractive` with `ENV` [should be actively discouraged](https://github.com/moby/moby/issues/4032#issuecomment-34597177). [Use `ARG` instead](https://github.com/moby/moby/issues/4032#issuecomment-192327844). – Nathaniel Jones Aug 12 '22 at 20:01
  • @StephanSamuel Glad I'm not the only one. What's the reason behind `ARG DEBIAN_FRONTEND=noninteractive` only working _sometimes_? – Nathaniel Jones Aug 12 '22 at 20:06
  • @StephanSamuel `ARG` variables only exist in the build stage they're declared in. I.e. they are ["cleared" by following `FROM` instructions](https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact). – Nathaniel Jones Aug 12 '22 at 20:29
  • Fixed it to be one line -- misc commenters are correct, that's how it should be done. – Stabledog Nov 12 '22 at 13:02
22

To avoid playing directly with symlinks and to run configuration only once, I suggest to use debconf-set-selections command:

echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections
echo 'tzdata tzdata/Zones/Europe select Paris' | debconf-set-selections
DEBIAN_FRONTEND="noninteractive" apt install -y tzdata
Pascal H.
  • 1,431
  • 8
  • 18
  • 1
    This did not work for me in current ubuntu:latest – Jakuje Aug 20 '21 at 16:12
  • I test it again using the following Dockerfile and it seems to be ok. What is your issue? `FROM ubuntu:latest` `RUN echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections` `RUN echo 'tzdata tzdata/Zones/Europe select Paris' | debconf-set-selections` `RUN apt update && DEBIAN_FRONTEND="noninteractive" apt install -y tzdata` – Pascal H. Aug 22 '21 at 14:44
  • I ended up doing the same that is now working. Sorry for the noise. – Jakuje Aug 23 '21 at 09:11
  • 2
    This really should be the accepted answer. – tripleee Oct 28 '21 at 18:50
13

I have recently found the following solution in a Dockerfile building the Cingulata FHE library:

ln -snf /usr/share/zoneinfo/$(curl https://ipapi.co/timezone) /etc/localtime

It basically uses the API provided by ipapi.co to retrieve the timezone information. This automatically configures the timezone properly instead of skipping the dialog and using the default (UTC).

Patrick
  • 1,046
  • 2
  • 10
  • 31
  • 2
    Smart idea to use https://ipapi.co/timezone, provided that the timezone to set is same as where the machine is located. This may not work for e.g. with user in Asia, but server in US. – Henry Luo May 19 '21 at 06:30
10

All credit for this should go to @PYA but the right order should be:

ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
export DEBIAN_FRONTEND=noninteractive
apt-get install -y tzdata
dpkg-reconfigure --frontend noninteractive tzdata
jpruiz114
  • 418
  • 5
  • 11
3

Here is how I did it:

echo 1 > input.txt
echo 1 >> input.txt
apt-get install -y tzdata < input.txt
ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
echo America/Los_Angeles > /etc/timezone

The first two echo statements create a text file that contains the selection numbers for the geographic area menu and the city/region menu. This file is then used to provide input to the apt-get install command. The tzdata package will be installed without asking for any user input. The timezone will be set to Africa/Abidjan as if you entered 1 and 1 in response to the prompts you would normally get. Then I change the timezone to what I want with the last two commands.

Instead of 1 and 1, you could use the actual numbers for the geographic area and city/region that you want, but it seems to me that those numbers could change.

Mike Maready
  • 121
  • 1
  • 1
3

here is what worked for me:

from ubuntu:bionic
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y tzdata

RUN unlink /etc/localtime
RUN ln -s /usr/share/zoneinfo/America/New_York /etc/localtime
grantr
  • 878
  • 8
  • 16
0

After reading the comments, I did two steps below to use the TZ environment variable:

  • Added the following to the Dockerfile
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends tzdata && apt-get clean
  • Added the following to the docker CMD script:
    if [ ! -z "${TZ}" ]; then
        echo "${TZ}" > /etc/timezone
        dpkg-reconfigure -f noninteractive tzdata
    fi

This worked for me and allowed me to set the time zone when starting the container.

MrJacqes
  • 373
  • 1
  • 4