2

I'm building a docker image based on Ubuntu 14.04 and am having troubles to set the locale correctly.

(I know 14.04 is EOL and all but it should still work as well, right? I was denied support from the Ubuntu people on askubuntu.com, hence I'm trying my luck here)

My Dockerfile looks like:

COPY .bashrc /root/.bashrc
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get install -y build-essential \
                       locales
RUN dpkg-reconfigure locales
WORKDIR /home/prs/

Where .bashrc is:

export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

it will build with no errors docker build -t "test" . but when I run it, I get the following output:

$ docker run -it test
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
root@d09247a538eb:/# source /root/.bashrc 
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
root@d09247a538eb:/# 

I also tried:

echo "LANG=en_US.UTF-8" > /etc/locale.conf

I still get:

# locale-gen
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

What's going on with this? And how can the locale be set correctly?

UPDATE:

It seems like that if I base my container image off of Ubuntu 18.04, I get to choose a locale when I type # dpkg-reconfigure locales but with 14.04 (which is what I currently need) I get the following:

# dpkg-reconfigure locales
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = "en_US.UTF-8",
        LC_ALL = "en_US.UTF-8",
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

AS suggested below by Eduardo Trápani (@EduardoTrápani), I also tried to run the locale setting manually:

# echo "en_US.UTF-8 UTF-8" | sudo tee -a /etc/locale.gen
en_US.UTF-8 UTF-8
# locale-gen
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

Another hint may be, that there is nothing in the locales/sup[ported.d directory (which should be the result of locale-gen if I understand this correctly from http://manpages.ubuntu.com/manpages/precise/man8/locale-gen.8.html):

# ls -l /var/lib/locales/supported.d/  

total 0

4
  • 1
    Does this also happen on a more modern Ubuntu, such as 20.04?
    – bk2204
    Dec 31, 2020 at 3:31
  • not quite the same, please see UPDATE above.
    – stdcerr
    Dec 31, 2020 at 3:42
  • Try modifying /etc/locale.gen and running locale-gen like in stackoverflow.com/a/28406007/10931455.
    – Freddy
    Dec 31, 2020 at 3:58
  • @Freddy there was no /etc/locale.gen, I had to create it first.
    – stdcerr
    Dec 31, 2020 at 4:11

2 Answers 2

3

The problem you're seeing is that by default, no locales are built into Docker container except C (also known as POSIX) and C.UTF-8 (the UTF-8 version). That's because glibc ships with a huge number of locales which take up a decent amount of space and Debian and Ubuntu, to save space, ship only compressed versions in the locales package, requiring the specific locales to be built on the system.

If you're just looking for an English language locale with UTF-8, then C.UTF-8 may meet your needs and avoid needing to build a new locale in your container. You can simply use LC_ALL=C.UTF-8 docker run -it test.

However, if you need a U.S. English locale specifically (e.g., because you for some strange reason really like the Avoirdupois system and want to use it with LC_MEASUREMENT), your easiest solution is to install the locales-all package. That provides pre-built versions of all locales.

Alternatively, if you're desperate for space, you can update your Dockerfile to add this line:

RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen

That will build just the locale you want.

The final solution is to have your .bashrc detect whether your locale is valid and set it to something else if it's not. Since, despite being a native English speaker, I often use a French-language locale, which is not always available on all systems I use, I've adopted this approach. You can run the following command, which will exit 0 if the locale $locale exists and nonzero if it does not:

$ perl -MPOSIX=locale_h -E 'exit !setlocale(LC_ALL, $ARGV[0]);' "$locale" \
  2>/dev/null
2
  • HI bk2204, I did try the C.UTF-8 version which worjked fine but I unfortunately need to set it to en_US.UTF-8 and there is no locales-all package I could install.
    – stdcerr
    Dec 31, 2020 at 17:29
  • The locales-all package is available in newer versions, such as 16.04 and newer. It sounds like you'll need to update to an OS version that presently has support and updates.
    – bk2204
    Dec 31, 2020 at 18:28
2

You should add the locale to /etc/locale.gen, build it, and then you can use it:

$ sudo echo "en_US.UTF-8 UTF-8" | sudo tee -a /etc/locale.gen
$ sudo locale-gen

You can put those commands in your docker file.

9
  • 1
    Hi Eduardo, I did add both these commands to my Dockerfile but it still complains: bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory even though there now is a /etc/locale.gen with the following contents: en_US.UTF-8 UTF-8
    – stdcerr
    Dec 31, 2020 at 4:14
  • 1
    locale-gen should report the locales it is building. If there is an error inside the docker context you might be able to see it if you run it manually. Dec 31, 2020 at 5:10
  • docker doesn't print more than RUN locale-gen & ---> Running in 52a4316f2a63 even when I build with --no-cache and when I execute locale-gen when the image is running, I get /bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
    – stdcerr
    Dec 31, 2020 at 17:41
  • 1
    Is that the full output when you do it manually, just the error and then the prompt, right away? Because locale-gen does not stop if it cannot set the locale, it's more a warning than an error. Dec 31, 2020 at 19:36
  • 1
    Last thing I'd try is to explicitely install locales with RUN apt-get install -y locales before you run locale-gen. Because all needed files should be there but your docker image might have a trimmed down version of the package. Dec 31, 2020 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.