Como definir a localidade dentro de um contêiner Docker Debian / Ubuntu?

124

Estou executando um contêiner do Ubuntu Docker. Tenho um teclado norueguês e preciso usar caracteres noruegueses (øæå).

Minha codificação de caracteres do Terminal está definida como UTF-8 e estou conectado ao meu contêiner usando SSH. No entanto, não consigo digitar caracteres noruegueses, nem copiar e colar caracteres noruegueses, nem usar CTL + SHIFT + U + 00f8.

Eu tentei:

locale-gen nb_NO.UTF-8

mas nada mudou. Como faço para definir a localidade e o teclado dentro de um contêiner do Docker?

mtmacdonald
fonte

Respostas:

172

Coloque em seu Dockerfile algo adaptado de

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

isso foi extraído de uma excelente postagem sobre o assunto, de

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

user2915097
fonte
1
Não está funcionando quando você usa debian: jessie como contêiner de base
iDexter
22
você precisa ao apt-get -y install localesusar o Ubuntu
user2915097 de
2
Tive de adicionar RUN touch /usr/share/locale/locale.aliasantes da chamada para locale-genpara evitar um erro fatal de arquivo não encontrado
Paul Keister
6
O sedroteiro é meio desajeitado. Tente s/# \(en_US\.UTF-8 .*\)/\1/evitar repetir a frase de pesquisa na string de substituição, capturando-a.
tripleee de
3
Se quiser evitar a criação de camadas adicionais, você pode escreverENV LANG=en_US.UTF-8 \ LANGUAGE=en_US \ LC_ALL=en_US.UTF-8
Andre Ravazzi
100

Quem usa o Debian também precisa instalar o localespacote.

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 

Essa resposta me ajudou muito.

mixel
fonte
63

Basta adicionar

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

em seu Dockerfile. (Você pode precisar ter certeza de que o localespacote está instalado.) Nada mais é necessário para a operação básica. Enquanto isso, fora do Ubuntu, locale-gennão aceita nenhum argumento, é por isso que nenhuma das 'correções' de uso funciona, por exemplo, no Debian. O Ubuntu aplicou locale-genum patch para aceitar uma lista de localidades a serem geradas, mas o patch no momento não foi aceito no Debian de nenhum outro lugar.

Andrewsh
fonte
1
Não funcionou para mim em uma imagem do Ubuntu. Essa resposta funcionou.
dialex de
4
Você poderia dar mais detalhes? C.UTF-8está disponível em todos os sistemas sem a necessidade de instalar nada, e deve ser principalmente o suficiente.
andrewsh,
Funciona com Docker ubuntu: imagem 18.04. Eu só precisava de "LANG". Eu também não precisei instalar locales.
wisbucky de
1
Se você deseja definir isso apenas no tempo de execução, pode definir o env vars no docker runcomando args: stackoverflow.com/questions/28405902/…
wisbucky
1
No Ubuntu, você precisa instalá-losapt-get install -y locales
gerardnico
27

Na verdade, aconteceu de eu ter sofrido do mesmo problema, mas nenhuma das respostas fornecidas está 100% funcionando com debian: latest, mesmo que elas forneçam boas dicas.

A maior diferença é que você deve se certificar de que locales e locales-all estão instalados, o último já contendo en_US.UTF-8, para que você não precise gerá-lo com local-gen ou dpkg-reconfigure .

Aqui está o que fiz em meu Dockerfile para que funcione:

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
fonte
2
A descrição do pacote locales-all contém: Este pacote contém os dados de localidade pré-compilados para todos os locais suportados. Uma alternativa melhor é instalar o pacote de locales e selecionar apenas os locais desejados, mas pode ser útil em uma máquina com pouca memória porque alguns arquivos de locale usam muita memória para serem compilados.
user2707671
E: O pacote 'locales-all' não tem nenhum candidato a instalação
AstraSerg
@AstraSerg: Estou muito surpreso que você tenha cometido esse erro. Qual é o resultado apt-cache show locales-all? Definitivamente, ainda é um pacote oficial e disponível no Debian.
Jean
@Jean root @ share: / # apt-cache show locales-all; cat / etc / issue N: Não é possível selecionar versões do pacote 'locales-all', pois é puramente virtual N: Nenhum pacote encontrado Ubuntu 18.04.1 LTS \ n \ l
AstraSerg
@AstraSerg: Na verdade, não sei sobre o Ubuntu, já que tentei isso apenas para o Debian (veja FROM debian: mais recente no snippet Dockerfile que forneci).
Jean
19

Especifique as variáveis ​​de ambiente LANGe LC_ALLusando -eao executar seu comando:

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

Não é necessário modificar o Dockerfile.

Dag Høidahl
fonte
2
Os -eargumentos funcionam com docker-compose também, a propósito.
Dag Høidahl
5
Isso funciona porque a maioria das distros inclui o C.UTF-8local. Eles geralmente não incluem localidades específicas do idioma (por exemplo en_US.UTF-8). Para isso você precisa instalar locales-all(grande) ou instalar localese executar locale-genapós terminar /etc/locale.gen.
Jonathon Reinhart
5

Dica: Navegue pelos fóruns de documentação do contêiner, como o Docker Forum .

Esta é uma solução para debian e ubuntu , adicione o seguinte ao seu 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
Eduardo santana
fonte
3

Vocês não precisam dessas coisas complexas para definir localidades no Ubuntu / Debian. Você nem precisa do /etc/local.genarquivo.

Simplesmente locale-genfará tudo e o autor só faltou o localespacote

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

Achei isso o mais simples e eficaz. Confirmo que funciona no Ubuntu 16.04.

Bumsik Kim
fonte
2

@A resposta do Mixel funcionou muito bem para a imagem docker baseada no Ubuntu que temos.

No entanto, também temos uma imagem docker baseada em centos para testar receitas via chef (usando o kitchen-dockerdriver). Um dos pacotes que pré-instalamos estava falhando ao instalar devido a nenhum local definido. Para instalar uma localidade, tive que executar o seguinte:

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

Consegui essa informação com esta resposta no ServerFault .

Depois de executar os comandos acima como parte do provisionamento do docker, o pacote foi instalado sem erros. De .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
fonte
1

Não gosto de ter variáveis ​​de ambiente Docker quando não espero que o usuário de uma imagem Docker as altere.

Basta colocá-lo em algum lugar em um RUN. Se você não tiver localidades UTF-8 geradas, poderá executar o seguinte conjunto de comandos:

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
Mitar
fonte
Essa parecia ser a única resposta sensata aqui, porque evita confundir as variáveis ​​de ambiente. No entanto, não funciona. localea saída não é alterada ao executar comandos subsequentes, nem ao executar RUNblocos subsequentes , nem ao construir outra imagem usando a imagem atual como base. Talvez alguma ação adicional seja necessária para realmente aplicar essas alterações?
user7860670
Os comandos acima são como você gera locales se não os encontrar. Se você quiser usá-los, você deve defini-los como uma variável de ambiente. Ou, como estou propondo nesta resposta diretamente dentro do RUN ou configurando ENVcomo o Docker ENV LC_ALL=en_US.UTF-8.
Mitar
-1

Em vez de redefinir o local após a instalação do pacote locales, você pode responder às perguntas que normalmente seriam feitas (que é desabilitado por noninteractive) antes de instalar o pacote para que os scripts do pacote configurem o locale corretamente, este exemplo define o local para inglês ( Britânico, 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
fonte
-1

Para mim, o que funcionou na imagem do ubuntu :

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
fonte
-1

Eu usei isto (depois 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! 👌')"

E imprime UTF8 works nice! 👌corretamente.

Carlos Pinzón
fonte