DockerコンテナにOracleXEをインストールする

先日 DockerをCentOSにインストールする記事を書きましたが、今回はDockerコンテナにOracle Express Edition ( 以下 OracleXE ) 11g をインストールする方法です。

はじめに

会社近くのおりがみ会館でゲットしたお折り紙でひな人形を手作りした今日この頃 ( 子供もちょっと手伝ってくれたが、小物も作ったら合計で 10 時間位かかった...  結構大変だった )、みなさまいかがお過ごしですか。

先日、Dockerの利用環境を作る 記事を書きましたが、今回はもう少し実践的なネタで、Docker コンテナ上に Oracle XE をインストールする方法に関して書きます。

写真は IM FREE より Blue Whale ( by Mike Baird )

環境

環境は以下になります。前回の記事と同じです。
OracleXEをインストールするコンテナのOSもCentOS6ベースのものから作成します。

OS CentOS 6.6 (Final)
Docker docker-io-1.3.1-2

DockerFile を使う

前回記事では使いませんでしたが、OracleXEのインストールにあたっては DockerFile を利用してインストールを行う方向で作業します。

DockerFile を利用することで、

  • Dockerイメージがどのようにして作成されるかを示す事ができる
    通常 DockerFile にはイメージ作成に必要な作業が全て含まれます。
    これによって、DockerFileを見る事で作成されたイメージがどういう機能を持っているかを把握できます。
  • Docker イメージ作成を自動化できる
  • 同じ環境を繰り返し構築する事ができる

( 私の場合も ) ちょっとした作業を行う場合等 「一々 DockerFile に書くのは面倒だ」 と思う事があるのは事実ですが、できる限り DockerFile を利用するのが望ましいでしょう。

下準備

Oracle XE (パッケージ) の取得

Oracle XEを事前に取得しておきます。
Oracle Database Express Edition 11g Release 2 からダウンロードできます。
今回は CentOS にインストールするので、Linux 版をダウンロードして下さい。
( 以下 oracle-xe-11.2.0-1.0.x86_64.rpm.zip を取得したものとして話を進めます )
※ダウンロードする際には、同意書への同意、及び、OTN ( Oracle Technology Network ) へのログインが必要になります。

作業ディレクトリを決める

作業を行うディレクトリを決めます。( 必要に応じて作成する )
後述する DockerFile やインストールに必要なファイル群をこのディレクトリに作成します。
以下 /tmp/work ディレクトリで作業するものとして話を進めます。
上で取得した Oracle XE の rpm ファイルをこのディレクトリにコピー(転送)しておいてください。

手順

Dockerfile の作成

先ず、Dockerfile を作成します。
ファイルの中身はOracle XE をインストールし、サービスを起動できる状態のコンテナイメージを作成するというもの。

# CentOS6 base image
FROM centos:centos6

# Maintainer of the image
MAINTAINER Masao Suda

# 必要なライブラリのインストール
RUN yum install -y libaio bc

# RPMパッケージ - コンテナにコピーするファイル
ADD Disk1/oracle-xe-11.2.0-1.0.x86_64.rpm /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm

# Oracle XE インストール
RUN yum localinstall -y /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm

# RPMファイルの削除
RUN rm -f /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm

# データベースのconfigure
RUN /etc/init.d/oracle-xe configure responseFile=/tmp/xe.rsp

# profile
RUN echo 'export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe' >> /etc/profile.d/oracle_profile.sh
RUN echo 'export PATH=$ORACLE_HOME/bin:$PATH' >> /etc/profile.d/oracle_profile.sh
RUN echo 'export ORACLE_SID=XE' >> /etc/profile.d/oracle_profile.sh

パッケージ (zip) ファイルの展開

作業ディレクトリで rpm.zip ファイルを展開します。

# unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip

作業ディレクトリ以下は以下のようになります。

作業ディレクトリ
│Dockerfile
├─ Disk1
│  │oracle-xe-11.2.0-1.0.x86_64.rpm
│  ├─ response
│  ├─ upgrade

レスポンスファイルの編集

Disk1/response/xe.rsp を編集します。

oracle ユーザのパスワードを設定する箇所があるので、ここを適当なパスワードに変更してください。

ビルドの実行

docker build コマンドを利用して Docker イメージをビルドします。

# cd 作業ディレクトリ
# docker build -t oraclexe .

問題

上記 Dockerfile でビルドできるだろうと思っていたのですが、ダメでした。

必要なライブラリ ( libaio, bc ) のインストール、ADDによるコンテナへのファイルの追加 までは問題なかったのですが、oracle-xe のインストールで以下のエラーが発生

docker 0.11以降ではセキュリティ上の理由から /proc, /sys へのアクセスは制限されたらしい。
参考 : Read-only file system errors during image build on Docker 0.11.1

Step 7 : RUN yum localinstall -y /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm
 ---> Running in d63956d5e679
Loaded plugins: fastestmirror
Setting up Local Package Process
Examining /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm: oracle-xe-11.2.0-1.0.x86_64
Marking /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm to be installed
Determining fastest mirrors
 * base: mirror.nus.edu.sg
 * extras: mirror.vodien.com
 * updates: mirror.vodien.com
Resolving Dependencies
--> Running transaction check
---> Package oracle-xe.x86_64 0:11.2.0-1.0 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package       Arch       Version        Repository                        Size
================================================================================
Installing:
 oracle-xe     x86_64     11.2.0-1.0     /oracle-xe-11.2.0-1.0.x86_64     564 M

Transaction Summary
================================================================================
Install       1 Package(s)

Total size: 564 M
Installed size: 564 M
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Error in PREIN scriptlet in rpm package oracle-xe-11.2.0-1.0.x86_64
error: "Read-only file system" setting key "kernel.sem"
error: "Read-only file system" setting key "kernel.shmmax"
error: "Read-only file system" setting key "net.ipv4.ip_forward"
error: "Read-only file system" setting key "net.ipv4.conf.default.rp_filter"
error: "Read-only file system" setting key "net.ipv4.conf.default.accept_source_route"
error: "Read-only file system" setting key "kernel.sysrq"
error: "Read-only file system" setting key "kernel.core_uses_pid"
error: "Read-only file system" setting key "net.ipv4.tcp_syncookies"
error: "Read-only file system" setting key "net.bridge.bridge-nf-call-ip6tables"
error: "Read-only file system" setting key "net.bridge.bridge-nf-call-iptables"
error: "Read-only file system" setting key "net.bridge.bridge-nf-call-arptables"
error: "Read-only file system" setting key "kernel.msgmnb"
error: "Read-only file system" setting key "kernel.msgmax"
error: "Read-only file system" setting key "kernel.shmmax"
error: "Read-only file system" setting key "kernel.shmall"
error: %pre(oracle-xe-11.2.0-1.0.x86_64) scriptlet failed, exit status 255
error:   install: %pre scriptlet failed (2), skipping oracle-xe-11.2.0-1.0
  Verifying  : oracle-xe-11.2.0-1.0.x86_64                                  1/1

Failed:
  oracle-xe.x86_64 0:11.2.0-1.0

Complete!
INFO[0157] The command [/bin/sh -c yum localinstall -y /tmp/oracle-xe-11.2.0-1.0.x86_64.rpm] returned a non-zero code: 1

回避策

--privileged オプションを付けて docker を起動する事で、上記問題を回避する事ができるとの事。
但し、Dockerfile ( docker build ) を利用する場合には使えない様子。

仕方がないので、Dokcerfile での一発インストールは断念 orz
以下 -- privileged オプションを使っての作業に。

  1. centos6 イメージから docker コンテナを起動
    ※上記Dockerfile の ADD まで実行し、必要なファイルを追加したイメージを作成して作業する方法でも構いません。
    その場合は以下必要ライブラリのインストール作業、及び、ファイルの転送作業は適宜飛ばしてください。

    # docker run -it --privileged centos:centos6 /bin/bash
    
  2. 以下コンテナでの作業。
    インストールに必要なパッケージを yum でインストール
    # yum install wget unzip libaio bc
    
  3. 必要なファイル群を取得 unzip して インストール
    ( 私の場合は社内の適当な http サーバ上に必要ファイルを(一時的に)置いて wget で取得した )
    # cd 作業ディレクトリ
    # wget ...
    # unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
    # rpm -ivh oracle-xe-11.2.0-1.0.x86_64.rpm
    
  4. メモリー内ファイル・システムの作成
    ( 実施せずに configure したらエラーになった )
    /etc/fstab を編集
    # vi /etc/fstab
    
    以下を追加
    shmfs /dev/shm tmpfs size=2048m 0 0
    

    マウント

    # mount /dev/shm
    
  5. configure
    # /etc/init.d/oracle-xe configure
    

    パスワードを二回聞かれるので、適当なパスワードを設定して下さい。
    ポート番号等は環境に併せて適宜設定して下さい ( 特に理由が無ければパスワード以外はエンターキー押下で問題ない )。

  6. /etc/profile.d/oracle.sh の作成
    # vi /etc/profile.d/oracle.sh
    
    以下内容で編集
    export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
    export PATH=$ORACLE_HOME/bin:$PATH
    export ORACLE_SID=XE
    
    sed -i -E "s/HOST = [^)]+/HOST = $HOSTNAME/g" /u01/app/oracle/product/11.2.0/xe/network/admin/listener.ora
    

    ※sed ... 部分では listener.ora のホスト名を変更しています。docker コンテナの場合、再起動する度にホスト名が変更される可能性があるため、起動時に変更します。

    この設定を適用しておきます。
    # source /etc/profile.d/oracle.sh
    
  7. oracle-xe 再起動
    # /etc/rc.d/init.d/oracle-xe restart
    

上記で Oracle XE 11g が起動する Docker コンテナが作成できました。

※尚、この手順で作成される Oracle XEの文字コードはUTF-8 になります。日本でOracle を利用している場合には、文字コードはシフトJISが利用されている場合が多いと思いますが、この場合、上記 /etc/profile.d/oracle.sh 作成後に、以下サイトにある手順を踏んで頂くことで 文字コードを変更する事が可能です。

参考 : Linux版Oracle 11g XE 文字コードをシフトJISに変更

接続確認

念のため接続確認します。

# su - oracle
$ sqlplus sys/manager as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on Tue Mar 3 07:33:29 2015

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


Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL>

接続できました。

コンテナのコミット

コンテナの設定が完了したら、コミットしておきましょう。
Docker ホスト上から

# docker commit コンテナID レポジトリ名[:タグ名]

まとめ

当初、Dockerfile を利用して Oracle XE をインストールした イメージ作成を行う事で、より実践的な利用方法のサンプル記事を書けるだろうと思っていたのですが、

error: "Read-only file system"

によって脆くもその野望は崩れ去りました。

当初の予定通りの記事にはなっていませんが、セキュリティ上の理由から Dockerfile だけでイメージ作成が行えない場合の回避策として備忘録の役目は果たせるのではないかと思います。

開発で oracle (xe) を利用する場合に、docker イメージが用意されていると結構便利です。Docker の練習兼ねて作成してみてはいかがでしょうか。