221

I'm running a Ubuntu Docker container. I have a Norwegian keyboard and need to use Norwegian characters (øæå).

My Terminal character encoding is set to UTF-8 and I'm connected to my container using SSH. However, I'm unable to type Norwegian characters, nor copy and paste Norwegian characters, nor use CTL+SHIFT+U+00f8.

I tried:

locale-gen nb_NO.UTF-8 

but nothing changed. How do I set the locale and keyboard inside a Docker container?

0

18 Answers 18

312

Put in your Dockerfile something adapted from

# Set the locale RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ locale-gen ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 

If you run Debian or Ubuntu, you also need to install locales to have locale-gen with

apt-get -y install locales 

this is extracted from the very good post on that subject, from

https://web.archive.org/web/20230323021946/http://jaredmarkell.com/docker-and-locales/

Sign up to request clarification or add additional context in comments.

13 Comments

you need to apt-get -y install locales when using Ubuntu
I had to add RUN touch /usr/share/locale/locale.alias before the call to locale-gen in order to avoid a fatal file not found error
The sed script is kind of clumsy. Try s/# \(en_US\.UTF-8 .*\)/\1/ to avoid repeating the search phrase in the replacement string by capturing it.
If you want to avoid creating additional layers, you can write ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US \ LC_ALL=en_US.UTF-8
ENV is not creating additional layers, as per documentation in docs.docker.com/develop/develop-images/…. So you can have multiple ENV commands without problems.
|
137

Those who use Debian also have to install locales package.

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y locales RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ dpkg-reconfigure --frontend=noninteractive locales && \ update-locale LANG=en_US.UTF-8 ENV LANG en_US.UTF-8 

This answer helped me a lot.

Comments

100

Just add

ENV LANG C.UTF-8 ENV LC_ALL C.UTF-8 

into your Dockerfile. (You may need to make sure the locales package is installed.) Nothing else is needed for the basic operation. Meanwhile, outside of Ubuntu, locale-gen doesn’t accept any arguments, that’s why none of the ‘fixes’ using it work e.g. on Debian. Ubuntu have patched locale-gen to accept a list of locales to generate but the patch at the moment has not been accepted in Debian or anywhere else.

6 Comments

Didn't work for me on an Ubuntu image. This answer worked though.
Could you please give any details? C.UTF-8 is available on all systems without the need to install anything, and it should be mostly enough.
Works with Docker ubuntu:18.04 image. I only needed "LANG". I did not need to install locales either.
If you only want to set this at runtime, you could set the env vars in the docker run command args instead: stackoverflow.com/questions/28405902/…
On Ubuntu, you need to install them apt-get install -y locales
|
46

I actually happened to have suffered from the same problem, but none of the provided answers are 100% working with debian:latest, even if they provide good hints.

The biggest difference is that you should make sure both locales and locales-all are installed, the latter already containing en_US.UTF-8, so you don't have to generate it with local-gen or dpkg-reconfigure.

Here's what I've done in my Dockerfile to make it work:

FROM debian:latest RUN apt-get update RUN apt-get install -y locales locales-all ENV LC_ALL en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US.UTF-8 

5 Comments

The description of the locales-all package has: This package contains the precompiled locale data for all supported locales. A better alternative is to install the locales package and only select desired locales, but it can be useful on a low-memory machine because some locale files take a lot of memory to be compiled.
E: Package 'locales-all' has no installation candidate
@AstraSerg: I'm very surprise you got that error. What's the ouput of apt-cache show locales-all? It's definitely still an official package and available in Debian.
@Jean root@share:/# apt-cache show locales-all; cat /etc/issue N: Can't select versions from package 'locales-all' as it is purely virtual N: No packages found Ubuntu 18.04.1 LTS \n \l
@AstraSerg: I actually don't know for Ubuntu since I tried that for Debian only (see FROM debian:latest in the Dockerfile snippet I provided).
31

Specify the LANG and LC_ALL environment variables using -e when running your command:

docker run -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -it --rm <yourimage> <yourcommand> 

It's not necessary to modify the Dockerfile.

2 Comments

The -e arguments work with docker-compose also, by the way.
This works because most distros include the C.UTF-8 locale. They do not usually include language-specific locales (e.g. en_US.UTF-8). For that you need ot install locales-all (big) or install locales and run locale-gen after ending /etc/locale.gen.
9

You guys don't need those complex things to set locales on Ubuntu/Debian. You don't even need /etc/local.gen file.

Simply locale-gen will do everything and the author only missed locales package.

RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \ && locale-gen "en_US.UTF-8" ENV LANG=en_US.UTF-8 \ LANGUAGE=en_US:en \ LC_ALL=en_US.UTF-8 

I found this the simplest and the most effective. I confirm it works on Ubuntu 16.04.

1 Comment

This didn't work for me, with a Debian Buster-based image. For more details and what worked: stackoverflow.com/a/76480234/227779
7

Tip: Browse the container documentation forums, like the Docker Forum.

Here's a solution for debian & ubuntu, add the following to your Dockerfile:

RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \ && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 ENV LANG en_US.UTF-8 

Comments

5

I dislike having Docker environment variables when I do not expect user of a Docker image to change them.

Just put it somewhere in one RUN. If you do not have UTF-8 locales generated, then you can do the following set of commands:

export DEBIAN_FRONTEND=noninteractive apt-get update -q -q apt-get install --yes locales locale-gen --no-purge en_US.UTF-8 update-locale LANG=en_US.UTF-8 echo locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8 | debconf-set-selections echo locales locales/default_environment_locale select en_US.UTF-8 | debconf-set-selections dpkg-reconfigure locales 

2 Comments

This seemed to be the only sane answer here because it avoids screwing with environment variables. However it does not work. locale output is not changed when executing subsequent commands, nor when executing subsequent RUN blocks, nor when building another image using current image as base. Maybe some additional action is required to actually apply these changes?
The commands above is how you generate locales if you are missing them. If you want to use them, you have to set it as environment variable. Or, as I am proposing in this answer directly just inside of RUN, or, by setting Docker ENV like ENV LC_ALL=en_US.UTF-8.
4

I used this (after RUN apt-get install -y python3):

RUN apt-get install -y locales RUN apt-get install -y language-pack-en ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 RUN python3 -c "print('UTF8 works nice! 👌')" 

And it prints UTF8 works nice! 👌 correctly.

2 Comments

For me, setting only LANG or LC_ALL was sufficient for python to output UTF-8. I realize that all 3 are listed in the locale command, but may not actually be required. I'm not sure. I haven't looked into locale in enough detail.
This is the only answer that mentions Ubuntu language-pack-* packages, which you need to add in order to have translations for a lot of Linux utilities. Other answers work fine for Debian, but on Ubuntu without the language-pack-es, gpg --help (for example) will be in English, not Spanish.
2

@Mixel's answer worked great for the Ubuntu-based docker image we have.

However, we also have a centos-based docker image for testing recipes via chef (using the kitchen-docker driver). One of the packages we pre-install was failing to install due to no locale being set. In order to get a locale installed, I had to run the following:

localedef -c -f UTF-8 -i en_US en_US.UTF-8 export LC_ALL=en_US.UTF-8 

I got this information from this answer on ServerFault.

After running the above commands as part of the docker provisioning the package installed without any errors. From .kitchen.yml:

platforms: - name: centos7 driver_config: image: #(private image) platform: centos provision_command: - localedef -c -f UTF-8 -i en_US en_US.UTF-8 - export LC_ALL=en_US.UTF-8 

Comments

2

add into "Dockerfile":

# Set the locale in container RUN apt-get -y install locales RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \ locale-gen ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 

enjoy it!

1 Comment

It works with docker postgres 12.7. Just as a side note, there's no need to set those ENV variables, with the first two RUN commands is enough (even in some distributions the locales package is already installed)
1

for ubuntu 14.04, where there is no file in /etc/locale.gen, but it share the file /etc/default/locale. So for trusty(ubuntu 14.04), just run

RUN apt-get -y install locales && \ update-locale LANG=en_US.UTF-8 

So that at least the global default locale is changed from annoy 'POSIX' to the locale you want.

Comments

1

I had problem setting locale in ubuntu container. It wasn't read from /etc/default/locale. I get:

LANG= LANGUAGE= LC_CTYPE="POSIX" LC_NUMERIC="POSIX" LC_TIME=C.UTF-8 LC_COLLATE="POSIX" LC_MONETARY="POSIX" LC_MESSAGES="POSIX" LC_PAPER="POSIX" LC_NAME="POSIX" LC_ADDRESS="POSIX" LC_TELEPHONE="POSIX" LC_MEASUREMENT="POSIX" LC_IDENTIFICATION="POSIX" LC_ALL= 

So, I set locale as system environment variables. Which will be read when login. source

So, what I did is set

sudo locale-gen en_US.UTF-8 sudo update-locale LANG=en_US.UTF-8 

and

sudo nano /etc/profile.d/set-locale.sh

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

Now my locale is:

LANG=en_US.UTF-8 LANGUAGE=en LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" LC_ALL=en_US.UTF-8 

Comments

0

Rather than resetting the locale after the installation of the locales package you can answer the questions you would normally get asked (which is disabled by noninteractive) before installing the package so that the package scripts setup the locale correctly, this example sets the locale to english (British, UTF-8):

RUN echo locales locales/default_environment_locale select en_GB.UTF-8 | debconf-set-selections RUN echo locales locales/locales_to_be_generated select "en_GB.UTF-8 UTF-8" | debconf-set-selections RUN \ apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y locales && \ rm -rf /var/lib/apt/lists/* 

Comments

0

You can use a command and args to install locales, set the default locale then run /docker_entry.sh:

Use /bin/bash as command and a entire script as argument.

Example to install all locales (note recommended, specify specify which ones you need)

Command:

["/bin/bash", "-c"] 

Args:

| apt-get update && apt-get install -y locales && sed -i 's/^# \\(.*\\)/\\1/' /etc/locale.gen && locale-gen; export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8; /docker-entrypoint.sh 

Comments

0

This was useful for me, trying to add an additional locale to the postgres:13.2 container without a custom Dockerfile. I first tried the approach of running locale-gen with a named locale (e.g. locale-gen sv_FI.UTF-8), but this didn't seem to work for me (the image is Debian Buster-based in this case). It overwrites the locale DB with an empty list of locales, breaking the Postgres startup.

This worked nicely for me, though. You need to add both the default en_US.UTF-8 locale in this case AND your custom locale, since the /etc/locale.gen has all locales disabled by default.

Here's an excerpt from my docker-compose.yml file:

entrypoint: - /bin/sh - -c - sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && sed -i -e 's/# sv_FI.UTF-8 UTF-8/sv_FI.UTF-8 UTF-8/' /etc/locale.gen && locale-gen && docker-entrypoint.sh postgres 

Comments

-1

For me what worked in ubuntu image:

FROM ubuntu:xenial USER root ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && apt-get install --no-install-recommends -y locales && rm -rf /var/lib/apt/lists/* RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment RUN echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen RUN echo "LANG=en_US.UTF-8" > /etc/locale.conf 

Comments

-1

In Debian I had to...

1 - Edit the locale file

sudo nano /etc/default/locale 

2 - Uncomment the locale I wanted to use in my case "es_ES.UTF-8 UTF-8"

3 - Run:

sudo locale-gen 

Hopefully this saves time for those who encounter this problem in Debian.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.