mtmacdonald
mtmacdonald

Reputation: 15080

How to set the locale inside a Debian/Ubuntu Docker container?

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?

Upvotes: 214

Views: 251138

Answers (18)

user2915097
user2915097

Reputation: 32176

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/

Upvotes: 305

Per Lundberg
Per Lundberg

Reputation: 4220

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

Upvotes: 0

Tarek
Tarek

Reputation: 11

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

Upvotes: 1

Fabio Mazzo
Fabio Mazzo

Reputation: 349

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

Upvotes: 0

D.Snap
D.Snap

Reputation: 1780

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.

Upvotes: -1

Mitar
Mitar

Reputation: 7030

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

Upvotes: 5

Frank Zhou
Frank Zhou

Reputation: 11

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.

Upvotes: 1

Soheil TT
Soheil TT

Reputation: 61

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!

Upvotes: 2

andrewsh
andrewsh

Reputation: 1169

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.

Upvotes: 98

Carlos Pinzón
Carlos Pinzón

Reputation: 1427

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.

Upvotes: 4

alexopoulos7
alexopoulos7

Reputation: 912

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

Upvotes: -1

Eduardo Santana
Eduardo Santana

Reputation: 6110

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

Upvotes: 7

Bumsik Kim
Bumsik Kim

Reputation: 6623

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.

Upvotes: 8

Dag Høidahl
Dag Høidahl

Reputation: 8345

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.

Upvotes: 29

Matthew Buckett
Matthew Buckett

Reputation: 4371

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/*

Upvotes: 0

E. Moffat
E. Moffat

Reputation: 3288

@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

Upvotes: 2

Jean
Jean

Reputation: 682

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

Upvotes: 45

mixel
mixel

Reputation: 25846

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.

Upvotes: 136

Related Questions