LoginSignup
0
0

More than 5 years have passed since last update.

Libertyコンテナにロケールとタイムゾーンを設定する

Last updated at Posted at 2018-10-15

Libertyコンテナにロケールとタイムゾーンを設定する方法のメモ。

ロケールの設定

Libertyの公式DockerHubでDockerfileをたどっていくと、

websphere-liberty:javaee8 > websphere-liberty:kernel > ibmjava:8-jre > ubuntu:16.04

となっており元のイメージはUbuntuである。

ロケールを確認するとPOSIXとなっている。

$ docker run --rm -it websphere-liberty:18.0.0.3-kernel locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
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=
$

日本語ロケールを組み込むには以下のようにする。18.0.0.3のある変更からUSERrootではなく1001となっているので、apt-getを実行するためにはUSERを変更する必要がある。

Dockerfile
FROM websphere-liberty:18.0.0.3-kernel
USER 0
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y language-pack-ja && \
    rm -rf /var/lib/apt/lists/*
USER 1001
ENV LANG ja_JP.UTF-8

language-pack-jaをインストールすると依存性でlocales、language-pack-ja-baseもインストールされる。

LANGではなくLC_ALLを設定することもできるが、LANGのほうがよさそう。

ビルドする。

docker build -t websphere-liberty:18.0.0.3-kernel-ja .

コンテナを実行して確認する。

$ docker run --rm -it websphere-liberty:18.0.0.3-kernel-ja locale
LANG=ja_JP.UTF-8
LANGUAGE=
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=
$

localesだけインストールして以下とすることも可能。

Dockerfile
FROM websphere-liberty:18.0.0.3-kernel
USER 0
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y locales && \
    rm -rf /var/lib/apt/lists/* && \
    locale-gen ja_JP.UTF-8
USER 1001
ENV LANG ja_JP.UTF-8

Shift_JISの場合はlocale-genではなくlocaledefを使用する必要がある。

Dockerfile
FROM websphere-liberty:18.0.0.3-kernel
USER 0
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y locales && \
    rm -rf /var/lib/apt/lists/* && \
    localedef -f SHIFT_JIS -i ja_JP ja_JP.SJIS
USER 1001
ENV LANG ja_JP.SJIS
docker build -t websphere-liberty:18.0.0.3-kernel-ja-sjis .
$ docker run --rm -it websphere-liberty:18.0.0.3-kernel-ja-sjis locale
LANG=ja_JP.SJIS
LANGUAGE=
LC_CTYPE="ja_JP.SJIS"
LC_NUMERIC="ja_JP.SJIS"
LC_TIME="ja_JP.SJIS"
LC_COLLATE="ja_JP.SJIS"
LC_MONETARY="ja_JP.SJIS"
LC_MESSAGES="ja_JP.SJIS"
LC_PAPER="ja_JP.SJIS"
LC_NAME="ja_JP.SJIS"
LC_ADDRESS="ja_JP.SJIS"
LC_TELEPHONE="ja_JP.SJIS"
LC_MEASUREMENT="ja_JP.SJIS"
LC_IDENTIFICATION="ja_JP.SJIS"
LC_ALL=

タイムゾーンの設定

タイムゾーンはCentOSは環境変数を設定するだけでよいが、Ubuntuはそれだけでは足りないようだ。+9時間になっていない。

$ docker run --rm -it centos:7 date
Tue Oct 30 12:55:12 UTC 2018
$ docker run --rm -it -e "TZ=Asia/Tokyo" centos:7 date
Tue Oct 30 21:55:21 JST 2018
$ docker run --rm -it ubuntu:16.04 date
Tue Oct 30 12:55:34 UTC 2018
$ docker run --rm -it -e "TZ=Asia/Tokyo" ubuntu:16.04 date
Tue Oct 30 12:55:43 Asia 2018

tz-dataをインストールしてあれこれする。

Dockerfile
FROM websphere-liberty:18.0.0.3-kernel
USER 0
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata && \
    rm -rf /var/lib/apt/lists/* && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata
USER 1001
ENV TZ Asia/Tokyo

最後のENV TZ Asia/Tokyoはなくてもよい。

ビルドする。

docker build -t websphere-liberty:18.0.0.3-kernel-jst .

確認。

$ docker run --rm -it liberty-jst:kernel date
Mon Oct 15 17:07:55 JST 2018
$

オフライン環境でビルドする場合

事前にインターネットにつながる環境でパッケージを取得しておき、オフライン環境でビルドする。

オンライン環境でのパッケージの取得

カレントディレクトリーをマウントし、rootユーザーを指定してコンテナを起動して中に入る。

docker run --rm -it -u 0 -v $PWD:/work websphere-liberty:18.0.0.3-kernel bash

必要なパッケージをダウンロードオンリーモードで取得する。

apt-get update
apt-get install -y -d language-pack-ja
apt-get install -y -d tzdata

/var/cache/apt/archivesにダウンロードしたファイルがあるので、マウントしたディレクトリーにコピーする。

root@de5cc55463e1:/# ls -l /var/cache/apt/archives
total 6404
-rw-r--r-- 1 root root 2016058 Jun 28  2016 language-pack-ja-base_1%3a16.04+20160627_all.deb
-rw-r--r-- 1 root root 1147434 Jan  9  2018 language-pack-ja_1%3a16.04+20171210_all.deb
-rw-r--r-- 1 root root 3212542 Jan 17  2018 locales_2.23-0ubuntu10_all.deb
-rw-r----- 1 root root       0 Oct  5 18:08 lock
drwx------ 2 _apt root    4096 Oct 30 13:09 partial
-rw-r--r-- 1 root root  165668 Oct 29 10:08 tzdata_2018g-0ubuntu0.16.04_all.deb
root@de5cc55463e1:/# cp /var/cache/apt/archives/*.deb /work
root@de5cc55463e1:/# exit
exit
$ ls -l
total 12808
-rw-r--r--  1 sotoiwa  staff      278 10 30 21:52 Dockerfile
-rw-r--r--  1 sotoiwa  staff  2016058 10 30 22:10 language-pack-ja-base_1%3a16.04+20160627_all.deb
-rw-r--r--  1 sotoiwa  staff  1147434 10 30 22:10 language-pack-ja_1%3a16.04+20171210_all.deb
-rw-r--r--  1 sotoiwa  staff  3212542 10 30 22:10 locales_2.23-0ubuntu10_all.deb
-rw-r--r--  1 sotoiwa  staff   165668 10 30 22:10 tzdata_2018g-0ubuntu0.16.04_all.deb
$

オンライン環境でのビルド

Dockerfileは以下のようにする。以下は日本語ロケールの設定とタイムゾーンの設定を両方やる例。

FROM websphere-liberty:18.0.0.3-kernel
USER 0
COPY *.deb /tmp/
RUN DEBIAN_FRONTEND=noninteractive dpkg -i \
    /tmp/language-pack-ja-base_1%3a16.04+20160627_all.deb \
    /tmp/language-pack-ja_1%3a16.04+20171210_all.deb \
    /tmp/locales_2.23-0ubuntu10_all.deb \
    /tmp/tzdata_2018g-0ubuntu0.16.04_all.deb && \
    rm -rf /tmp/*.deb && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata
USER 1001
ENV LANG ja_JP.UTF-8
ENV TZ Asia/Tokyo

おまけ

Javaからどう見えるかも確認する。

確認用の簡単なJavaプログラムを作成する。

Main.java
import java.util.Date;
import java.util.Locale;

public class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.println("file.encoding = " + System.getProperty("file.encoding"));
        System.out.println("console.encoding = " + System.getProperty("console.encoding"));
        System.out.println("Date() = " + new Date());
        System.out.println("Locale Code = " + Locale.getDefault());
        System.out.println("こんにちは!");
    }
}

Main.javaをコンパイルしてLibertyのコンテナの中にクラスファイルを配置するDockerfileを作成する。LibertyのコンテナにはJDKが入っていないので、マルチステージビルドを使う。

Dockerfile
FROM ibmjava:8-sdk as builder
COPY Main.java /
RUN javac -encoding UTF-8 /Main.java
FROM websphere-liberty:18.0.0.3-kernel
COPY --from=builder /Main.class /

ビルドする。

docker build -t liberty-test:18.0.0.3-kernel .
$ docker run --rm -it liberty-test:18.0.0.3-kernel java Main
file.encoding = ANSI_X3.4-1968
console.encoding = null
Date() = Tue Oct 30 13:54:28 UTC 2018
Locale Code = en_US
??????

ロケールとタイムゾーンを設定してビルドする。

Dockerfile
FROM ibmjava:8-sdk as builder
COPY Main.java /
RUN javac -encoding UTF-8 /Main.java
FROM websphere-liberty:18.0.0.3-kernel
USER 0
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y language-pack-ja && \
    rm -rf /var/lib/apt/lists/*
RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata && \
    rm -rf /var/lib/apt/lists/* && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata
USER 1001
ENV LANG ja_JP.UTF-8
ENV TZ Asia/Tokyo
COPY --from=builder /Main.class /

ビルドする。

docker build -t liberty-test2:18.0.0.3-kernel .

確認する。

$ docker run --rm -it liberty-test2:18.0.0.3-kernel java Main
file.encoding = UTF-8
console.encoding = null
Date() = Tue Oct 30 22:57:43 JST 2018
Locale Code = ja_JP
こんにちは!
$

補足

コンテナにロケールやタイムゾーンを指定する必要があるかというと、そもそもあまり必要でないかもしれない。また、OSのレベルで設定しなくても、Javaのシステムプロパティーでfile.encodingconsole.encodinguser.timezoneを設定すればすむかもしれない。

$ docker run --rm -it liberty-test:18.0.0.3-kernel java -Dfile.encoding=UTF-8 -Duser.timezone=Asia/Tokyo Main
file.encoding = UTF-8
console.encoding = null
Date() = Tue Oct 30 22:58:35 JST 2018
Locale Code = en_US
こんにちは!
$

参考リンク

Ubuntu 16.04(xenial)のDockerコンテナのタイムゾーンを日本(JST)にする(Dockerfileで)

reconfigure timezone inside docker not working

Ubuntuでローカルにパッケージをダウンロード・インストールする

Docker で apt-get install するときに TERM 系のエラーが出る

0
0
0

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
0
0