93
74

More than 5 years have passed since last update.

Dockerfileで日本語ロケールを設定する方法。およびロケールエラーの回避方法。

Last updated at Posted at 2018-03-26

日本語処理を行う開発時などDockerfileで日本語ロケールの設定を行う場合の設定です。

せっかちな人のために

次の記述をglibcの更新処理(yum updateやyum reinstall glibc)より後方に記述します。
後方に記述しないと、glibcの更新によってlocaledefによるja_JP.UTF-8ロケールの追加がリセットされ、エラーが発生します。

RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"

上記はCentOS7の場合です。Ubuntuの場合は次のサイトなどを参照すると良いかもしれません。
https://qiita.com/suin/items/856bf782d0d295352e51

テスト環境

  • ホストOS: CentOS Linux release 7.4.1708 (Core)
  • Docker: Docker version 17.12.0-ce, build c97c6d6
  • コンテナOS: CentOS Linux release 7.4.1708 (Core)

ディストリビューションの設定コマンドは使えない

CentOS7のロケール設定コマンドである localectl はコンテナ上で実行できません。
systemctlなどと同様にエラーになります。

[user@container ~]# sudo localectl
Failed to create bus connection: No such file or directory

環境変数を直接設定する

Dockerfileでは環境変数を直接セットして日本語ロケールを設定します。
ところが、CentOS7の公式イメージでは設定できる既定ロケールが次の3つだけです。

[user@container ~]# locale -a
C
POSIX
en_US.utf8

このため、Dockerfileでは次のコマンドでロケールの追加を行う必要があります。
(この方法で作成するロケールをカスタムロケールというらしいです)

RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8

localedefコマンドの詳細については次のサイトなどを参照ください。
https://www.ibm.com/support/knowledgecenter/ja/SSLTBW_2.2.0/com.ibm.zos.v2r2.bpxa500/comlcdf.htm

上記で作成した日本語ロケールを次のコマンドで環境変数にセットします。

ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"

これで日本語環境のコンテナを作成できます。

ロケールエラーが発生する場合の回避方法

上記までの方法でDockerfileを作成したところ、テスト用コンテナでは問題なかったのですが、
複数の設定を入れた実用のDockerfileで次のようなエラーが発生するようになりました。
RUNコマンドの実行時などに発生します。

(error)
/bin/sh: warning: setlocale: LC_ALL: cannot change locale (ja_JP.UTF-8)
Failed to set locale, defaulting to C

作成されたコンテナで locale を確認すると LC_ALLなどの設定が落ちているようです。

[user@container ~]# locale
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
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=

どうやら glibc関連のパッケージを更新すると、カスタムロケールが消えてしまうようです。
(なぜ、LANGなどの環境変数には値が残っているのか不思議ですが)
作成したja_JP.UTF-8が消えてしまったので、環境変数の内容と不整合が起きてエラーが発生しているようです。
例えばyumは実行時にLC_ALLの内容を確認しているようです。

回避策は
・ yum update などglibcを更新するようなタスクはlocaledefより先に実行する

**2018/7/10追記**
次の記事で解説されている方法で回避可能と思われます。
https://qiita.com/teruo-oshida/items/08cb84efc2b581b0a439
(コメントいただきありがとうございます。)

私の場合日本語設定に関する記述をDockerfileの比較的上の方に記載していたので、後方で実施していたyum updateでglibcが更新され、追加したロケールが消えていたようです。

参考

次のサイトを参考にしています
Ubuntuでの設定方法
https://qiita.com/suin/items/856bf782d0d295352e51

Ubuntu / CentOSでの設定方法
https://qiita.com/yuki2006/items/6cea8c352e38f047b52a#comment-8e863c71962008035d0d

glibcとロケールについて
(こちらではカスタムロケールを保存場所を指定して作成する回避策が紹介されています)
https://qiita.com/kaikusakari/items/9fa7fcab0bb07b5122be

localeの詳細
https://qiita.com/aosho235/items/58e2e7acd5c2ee3641ff

localedefコマンドの詳細
https://www.ibm.com/support/knowledgecenter/ja/SSLTBW_2.2.0/com.ibm.zos.v2r2.bpxa500/comlcdf.htm

93
74
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
93
74