Oracle Express Editionの環境をDockerで構築し、SQL*Plusで日本語を利用する。


#【はじめに】
長らくPostgresやMySQLといったフリーのDBを使っていましたが、突如仕事でOracleを使うことになったので
Dockerを使ってOracle 11g のExpress Edition(Oracle XE)の環境を構築してみました。
その時の環境構築メモです。

#【前提】
・利用OSはWindows, Mac, LinuxのどれでもOKです。
・git、シェル(bashなど)、docker、docker-composeを利用します。
　※Windowsの場合、Git Bashが入っていると便利です。またdockerはDocker for Windowsを使うのが良いでしょう。
　
#【手順】
###1.dockerプロジェクトのclone
以下の通りOracle公式のgithubからdockerのプロジェクトをcloneします。

```sh:imageのclone
git clone https://github.com/oracle/docker-images
```

※cloneすると様々なプロダクトのフォルダが作られますが、今回はOracleDatabaseを利用します。


### 2. OracleXEのzipファイルダウンロード
以下のOracleのサイトからLinux版の「oracle-xe-11.2.0-1.0.x86_64.rpm.zip」をダウンロードします。

[OracleXEのダウンロード](http://www.oracle.com/technetwork/jp/database/database-technologies/express-edition/downloads/index.html)

### 3.zipファイルの配置
ダウンロードしたzipファイルを以下に配置します。

`./docker-images/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2`

### 4.イメージ作成用シェルの実行
`./docker-images/OracleDatabase/SingleInstance/dockerfiles`配下にある`buildcDockerImage.sh`を以下のように実行します。

`./buildDockerImage.sh -v 11.2.0.2 -x`

####（シェルのスイッチ）
以下2つのスイッチを指定します。
"-v": バージョンを指定します。今回は11.2.0.2をインストールします。
"-x": Express Editionをインストールすることを意味しています。

実行すると以下のようなログがコンソールに表示されます。

```sh:イメージ作成のコンソールログ
Checking if required packages are present and valid...
oracle-xe-11.2.0-1.0.x86_64.rpm.zip: OK
==========================
DOCKER info:
Containers: 9
 Running: 1
 Paused: 0
 Stopped: 8
Images: 116
Server Version: 18.03.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 773c489c9c1b21a6d78b5c538cd395416ec50f88
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: 949e6fa

・・・（長いので省略）・・・

  Oracle Database Docker Image for 'xe' version 11.2.0.2 is ready to be extended:

    --> oracle/database:11.2.0.2-xe

  Build completed in 68 seconds.
```

最後にBuild completedと表示されれば、イメージ作成完了です。
なお、コンソールログの最後から3行目にDockerのイメージ名が表示されます。
ここでは `oracle/database:11.2.0.2-xe` となっています。


### 5: イメージの確認
docker imagesで確認します。
```
$ docker images | grep oracle
oracle/database                   11.2.0.2-xe         161f7b1597e5        14 minutes ago      1.13GB
```

イメージ名が表示されればOKです。

### 6.Dockerfileとdocker-compose.ymlの作成
Dockerfileとdocker-compose.ymlを作成します。今回は以下のような感じで作ってみました。
※Dockerfileの名前はここではDockerfile-oracle-dbとしています。

```dockerfile:Dockerfile-oracle-db
FROM oracle/database:11.2.0.2-xe # 上で作ったイメージを指定します

RUN yum -y install vi
RUN echo 'TZ="Asia/Tokyo"' > /etc/sysconfig/clock
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN echo 'LANG="ja_JP.UTF-8"' > /etc/sysconfig/i18n
RUN echo 'LC_CTYPE="ja_JP.utf8"' >> /etc/sysconfig/i18n
RUN yum reinstall -y glibc-common
RUN yum reinstall -y glibc
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8

EXPOSE 11521 # 今回はポート番号11521で起動します
```

```dockerfile:docker-compose.yml
version: "2.0"

services:
  database:
   build:
     context: .
     dockerfile: Dockerfile-oracle-db
   container_name: oracle_test_db
   shm_size: 1g # 共有メモリを1GB以上にしないとコンテナ起動時にエラーが発生します。
   environment:
     - TZ=Asia/Tokyo
     - LANGUAGE=ja_JP.ja
     - LANG=ja_JP.UTF-8
     - NLS_LANG=Japanese_Japan.AL32UTF8 # sqlplusの日本語化でこの環境変数が必要になります。
     - ORACLE_PWD=Password # パスワードは適宜指定します。
   ports:
     - 11521:1521
   volumes:
     - ./sql:/docker-entrypoint-initdb.d/startup
```

#####【ポイント】
- 共有メモリを1g以上にしないとコンテナ起動時にエラーとるので `shm_size: 1g`を指定しています。
 
- 日本語を扱えるようにするため、ここでは環境変数`NLS_LANG`に
　`Japanese_Japan.AL32UTF8`をセットしています。
　これをセットしないと、日本語を含んだ文字列をinsertすると
　文字化けした状態でカラムに登録されてしまいます。

- コンテナ起動時に何かしらSQLを実行したい場合、/docker-entrypoint-initdb.d/startupに
　SQLファイルを配置したフォルダをマウントします。
　ここの例だと、ローカルの./sqlに配置したSQLファイルが自動的に実行されます。
　初回のテーブル作成やデータ登録などに役立ちます。

### 7.コンテナの起動
以下の通りdocker-composeを実行します。"-d"をつけてバックグラウンド実行します。

```sh:コンテナ起動
docker-compose up -d
```

コンソールログは以下のような感じです。

```sh:コンソールログ
Creating network "tmp_default" with the default driver
Building database
Step 1/10 : FROM oracle/database:11.2.0.2-xe
 ---> 161f7b1597e5
Step 2/10 : RUN yum -y install vi
 ---> Running in 92e1df7b1193
Loaded plugins: ovl
Resolving Dependencies
--> Running transaction check
---> Package vim-minimal.x86_64 2:7.4.160-4.el7 will be installed
--> Finished Dependency Resolution


・・・（長いので省略）・・・

Successfully built d2c5ce308313
Successfully tagged tmp_database:latest
Image for service database was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating oracle_test_db ... done

```

`docker ps`でコンテナが起動したか確認します。

```sh:コンテナの起動確認
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                             PORTS                                          NAMES
fd3cdc9c4449        tmp_database        "/bin/sh -c 'exec $O…"   34 seconds ago      Up 32 seconds (health: starting)   8080/tcp, 11521/tcp, 0.0.0.0:11521->1521/tcp   oracle_test_db
```
`oracle_test_db`という名前でコンテナが起動しています。

### 8.コンテナにログインし、sqlplusを実行します。
　ここではoracleユーザでログインするため`-u 1000`のスイッチをつけています。

```sh:コンテナのログインとsqlplusの起動
$ docker exec -u 1000 -it oracle_test_db  /bin/bash
bash-4.2$
bash-4.2$ sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on 木 8月 30 16:06:29 2018

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

ユーザー名を入力してください: system
パスワードを入力してください:


Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
に接続されました。
SQL>
```

上のようにコンソール上で日本語が表示されればOKです。

##【参考情報】
https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md