200

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?

andrewsh
  • 1,115
  • 7
  • 12
mtmacdonald
  • 14,216
  • 19
  • 63
  • 99

18 Answers18

289

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

http://jaredmarkell.com/docker-and-locales/

SergeyR
  • 468
  • 5
  • 10
user2915097
  • 30,758
  • 6
  • 57
  • 59
130

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.

andrewsh
  • 1,115
  • 7
  • 12
mixel
  • 25,177
  • 13
  • 126
  • 165
93

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 of anywhere else.

andrewsh
  • 1,115
  • 7
  • 12
  • 2
    Didn't work for me on an Ubuntu image. This [answer](https://stackoverflow.com/a/38553499/675577) worked though. – dialex Aug 16 '17 at 16:34
  • 5
    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. – andrewsh Sep 04 '17 at 19:26
  • 3
    Works with Docker ubuntu:18.04 image. I only needed "LANG". I did not need to install `locales` either. – wisbucky Aug 21 '19 at 17:39
  • 1
    If you only want to set this at runtime, you could set the env vars in the `docker run` command args instead: https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container/52004330#52004330 – wisbucky Aug 21 '19 at 17:47
  • 1
    On Ubuntu, you need to install them `apt-get install -y locales` – gerardnico Apr 14 '20 at 15:16
  • One-liner: `ENV LC_ALL=C.UTF-8 LANG=C.UTF-8`. – Константин Ван Jun 26 '21 at 09:51
41

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
Jean
  • 642
  • 5
  • 9
  • 3
    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. – user2707671 Aug 03 '18 at 17:11
  • E: Package 'locales-all' has no installation candidate – AstraSerg Dec 09 '18 at 09:30
  • @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 Dec 10 '18 at 10:35
  • @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 Dec 11 '18 at 14:26
  • @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). – Jean Feb 05 '19 at 16:24
29

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.

Dag Høidahl
  • 7,873
  • 8
  • 53
  • 66
  • 3
    The `-e` arguments work with docker-compose also, by the way. – Dag Høidahl Sep 11 '18 at 11:47
  • 9
    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`. – Jonathon Reinhart Mar 15 '19 at 21:51
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
mabraham
  • 2,806
  • 3
  • 28
  • 25
Eduardo Santana
  • 5,780
  • 3
  • 19
  • 21
7

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.

Bumsik Kim
  • 5,853
  • 3
  • 23
  • 39
6

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
Gabriel
  • 8,990
  • 6
  • 57
  • 101
Mitar
  • 6,756
  • 5
  • 54
  • 86
  • 1
    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? – user7860670 Jun 27 '20 at 11:00
  • 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`. – Mitar Jun 27 '20 at 17:23
3

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.

Carlos Pinzón
  • 1,286
  • 2
  • 15
  • 24
  • 1
    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. – erwin Sep 04 '22 at 09:18
  • 1
    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. – Dan Jul 05 '23 at 01:54
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
E. Moffat
  • 3,165
  • 1
  • 21
  • 34
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!

Soheil TT
  • 61
  • 4
  • 2
    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) – Edenshaw Apr 11 '22 at 20:04
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.

Frank Zhou
  • 11
  • 1
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/*
Matthew Buckett
  • 4,073
  • 1
  • 36
  • 28
0

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.

D.Snap
  • 1,704
  • 1
  • 22
  • 15
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
Fabio Mazzo
  • 329
  • 2
  • 7
0

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
Tarek
  • 1
  • 1
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 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
Per Lundberg
  • 3,837
  • 1
  • 36
  • 46
-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
alexopoulos7
  • 794
  • 7
  • 27