Oracle 11g XE のdocker環境を作成する

概要
---------------------
手順は以下の通り。

- コンテナイメージを作成
    - Windows/Linux版に対応
- docker-compose等で適度にセットアップ


対象
--------------------
- docker上でデータを含めたoracleインスタンスを立ち上げたい人

免責
------------
本ドキュメントに記載しているコード等は他参考資料由来のもの[^1]を除き、[WTFPL2ライセンス](https://ja.wikipedia.org/wiki/WTFPL)[^2]とし、いかなる保証もありません。
[^1]: 参考資料由来のものはvagrant関連コードとdocker build関連
[^2]: Wikipediaより:どうとでも勝手にしやがれクソッタレ・公衆利用許諾(契約)書
なお、エラーハンドリングは緩いので、改善願います。

準備
------------------------

任意フォルダ(tools)に [oracle-xe-11.2.0-1.0.x86_64.rpm.zip](http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html)(Oracle Database 11g Release 2 Express Edition for Linux x64) をダウンロードしておく。
任意フォルダ(tools)に次のバッチを配置する。
※インターネットへの接続が必要

```bat:get_oracle.bat(Windows用)
set WORKING_DIR=%TMP%\oracle_build_wk
set CURRENT_DIR=%CD%
echo %WORKING_DIR%
mkdir %WORKING_DIR%
copy oracle-xe-11.2.0-1.0.x86_64.rpm.zip %WORKING_DIR%\
cd %WORKING_DIR%
curl --output Dockerfile.xe    -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/Dockerfile.xe
curl --output checkDBStatus.sh -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/checkDBStatus.sh
curl --output runOracle.sh     -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/runOracle.sh
curl --output setPassword.sh   -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/setPassword.sh
curl --output xe.rsp           -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/xe.rsp

docker build %WORKING_DIR% --force-rm=true --no-cache=true --shm-size=1G --build-arg DB_EDITION=xe -t oracle/database:11.2.0.2-xe -f Dockerfile.xe > %CURRENT_DIR%\oracle11g_build.log 2>&1
cd %CURRENT_DIR%
del /Q /S %WORKING_DIR%
echo DONE

```


```sh:get_oracle.sh(Linux用)
#!/bin/sh

WORKDIR=/tmp/oracle11
CURRENTDIR=$(pwd)
mkdir $WORKDIR
cp oracle-xe-11.2.0-1.0.x86_64.rpm.zip $WORKDIR/
cd $WORKDIR
curl --output Dockerfile.xe    -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/Dockerfile.xe
curl --output checkDBStatus.sh -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/checkDBStatus.sh
curl --output runOracle.sh     -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/runOracle.sh
curl --output setPassword.sh   -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/setPassword.sh
curl --output xe.rsp           -sSL --url https://github.com/oracle/docker-images/raw/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2/xe.rsp

DOCKEROPS=""
VERSION=11.2.0.2
EDITION="xe"
DOCKERFILE="Dockerfile"
DOCKEROPS="--shm-size=1G $DOCKEROPS";
IMAGE_NAME="oracle/database:$VERSION-$EDITION"
DOCKERFILE="$DOCKERFILE.$EDITION"
docker build ./ --force-rm=true --no-cache=true \
       $DOCKEROPS --build-arg DB_EDITION=$EDITION \
       -t $IMAGE_NAME -f $DOCKERFILE
cd $CURRENTDIR
rm -rf $WORKDIR
echo DONE
```


実行
--------------------
`get_oracle.bat` または `get_oracle.sh` を実行する。
※必要に応じて実行権限を付与してください。(`chmod +x get_oracle.sh`)
エラーなく進めば、`oracle/database:11.2.0.2-xe` ができます。

docker-compose
----------------------
そのままだと、何らおいしくないので、レシピを載せておく。(永続化しないので、コンテナを作り直したらデータはリセットされます)

```yaml:docker-compose.yml
version: '3'

services:
  ## 必要に応じてその他サービスを記述
  oracledb_test:
    image: oracle/database:11.2.0.2-xe
    ports:
      - "1521:1521"
      #- "8080:8080"
    volumes:
      # ここのスクリプトがdba権限で動く。sqlplusやimp等を使いたい場合は、shファイルを配置しておくこと
      # なお、読み取り専用なので、ログファイルの出力を行う場合は、注意すること
      - ./oracledb/setup:/u01/app/oracle/scripts/setup:ro
      # 後からコンテ
      - ./oracledb/mnt:/mnt/local
    shm_size: 1g
    environment:
      - NLS_LANG=Japanese_Japan.UTF8
      - TZ=Asia/Tokyo
```


```sql:oracledb\setup\00_user_create.sql(UTF-8)

--勝手にパスワードを振られるので、変更する(絶対違うパスワードを指定してください)
ALTER USER sys IDENTIFIED BY manager;
ALTER USER system IDENTIFIED BY manager;

-- ユーザー作成
CREATE USER test_user IDENTIFIED BY test_user DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp QUOTA UNLIMITED ON users;
-- ロール作成
create role conn_testuser;
GRANT CREATE session, CREATE sequence, CREATE trigger, CREATE table, CREATE view, CREATE procedure, CREATE synonym TO conn_scn;
-- 権限付与
GRANT conn_testuser TO test_user;
--勝手に閉じてくれるので、exit等は不要

```

sqlでデータを投入する場合は、次のようなファイルを作成していく。

```sql:oracledb\setup\01_ddl.sql(UTF-8)

--スキーマを切り替え
ALTER SESSION SET CURRENT_SCHEMA = test_user;

--テーブル作成等

--勝手に閉じてくれるので、exit等は不要

```

おまけ: vagrant
------------------
Vagrant上でOracleインスタンスも立てちゃう場合は、次のように記載することでイメージの作成までやれる。
仮想マシンのインスタンスメモリは必ず2G以上にすること。(さもなくば、oracleを起動できません)

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # 中略
  #if Vagrant.has_plugin?("vagrant-cachier")
  #  config.cache.scope = :box 
  #end

  # 中略
  config.vm.provision "docker", run: "always"
  # ここから
  # Setup docker image for oracle 11g XE environment
    config.vm.synced_folder "./tools", "/tmp/tools", create: true
    config.vm.provision "shell", inline: <<-SHELL
      cd /tmp/tools
      /bin/sh ./get_oracle.sh
    SHELL
  # ここまで

  config.vm.provision "docker_compose",
                      compose_version: "1.24.1",
                      yml: "/vagrant/docker/docker-compose.yml",
                      run: "always"

end

```

参考文献
------------
- [Oracle Database on Docker](https://github.com/oracle/docker-images/tree/master/OracleDatabase) - github
- [vagrant+docker-compose環境を構築](https://qiita.com/maro_amoeba/items/740c9e84abaf89fc625f) - Qiita