Oracle Database 18c XE インストール (VPS+Docker使用)

最近会社で聞かれて答えたことをQiitaにまとめるために、実験や再現確認を目的としたOracle Database環境を作成しました。

[以前](https://qiita.com/szly/items/4b610f51a3172c04f5d2)は "Oracle Database 11g Express Edition (以下XE) on CentOS 6 on VirtualBox on Windows" という環境で作成しています。

今回は "Oracle Database 18c Express Edition (以下XE) on CentOS 7 on Docker on Vultr(VPS)" という環境で作成しています。

2020/04/14 : 会社で指摘されて"on Docker"を追加

# 環境とバージョンの選定

以前、11g環境をVirtualBox上に作りました。しかし、使用している端末にややスペック不足を感じています。Oracleの起動や使用に思ったよりも時間がかかります。新たにセットアップするとして、同じバージョンを入れるのではあまり勉強にならないだろうと、18cを使用することを考えました。加えて新しいバージョン18cを使うとなると、現行スペックでは苦しいかも。そのような理由から、VPSでの利用を考えていました。

しかしSakuraは月単価ベースの料金体系。常用利用目的でもない環境に月単価ベースの料金を払うことはできません。そこで、稼働時間ベースで利用可能なVPSである[Vultr](https://www.vultr.com/)を選びました。

Vultrが初期費用無料というのも選定理由です。とはいえ、Sakuraも昨年末あたりから[初期費用が無料になったようです](https://www.sakura.ad.jp/information/pressreleases/2019/10/10/1968201557/)。

[ある場所](https://cosol.jp/techdb/2019/05/use_oracle_database_no_charge/)には、"18cで機能制限が大幅に緩和された"と書かれていて、期待できます。

セットアップ所要時間、使用感、軽さ重さ、などがわかったら、VirtualBoxでも試してみようと思っています。

# インストール手順

以下の情報をベースにインストールしています。
http://www.ajisaba.net/db/oracle/ora18c_xe_dockerfile.html

## OSの準備

Vultrには[dockerを自動セットアップしてくれるインストールオプション](https://www.vultr.com/docs/one-click-docker/)があります。しかし、このオプションを使用したセットアップはうまくいきませんでした。そのため、今回のセットアップにはこのオプションを使用していません。

参考サイトには、ディスク13GB以上、メモリ1GB以上とあります。55GBプランを使えばよさそうです。55GBプランのスペックは、1CPU、SSD55GB、メモリ2GBです。月額$10、時間当たり約1.5円といったところでしょう。

ベースOSには"CentOS 7 without SELinux"を選択しました。

## 作業準備

### 作業アカウントの作成と設定

ここでは"linuser"という名前で作成することにします。sudo可能な状態にセットアップします。

```
[root@vultr ~]# useradd -m linuser
[root@vultr ~]# passwd linuser
    :
[root@vultr ~]# grep ^root /etc/sudoers | sed 's/root/linuser/' > /etc/sudoers.d/linuser
[root@vultr ~]# chmod 0440 /etc/sudoers.d/linuser
[root@vultr ~]# visudo --check
/etc/sudoers: parsed OK
/etc/sudoers.d/linuser: parsed OK
[root@vultr ~]#
```

### SSHログイン環境の整備

sshポートの変更、"PermitRootLogin no"、sshdの再起動を行います。それに伴って"iptables"の設定変更を行います。

```
[root@vultr ~]# vi /etc/ssh/sshd_config
     : ポート番号の変更、"PermitRootLogin no"の設定
[root@vultr ~]# iptables -L IN_public_allow --line-number
[root@vultr ~]# iptables -R IN_public_allow 1 -p tcp --dport ***** -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[root@vultr ~]# iptables -L IN_public_allow --line-number
[root@vultr ~]# systemctl restart sshd.service
[root@vultr ~]#
```

設定変更の後でVultr側のfirewallの設定も変更しておきます。SSHポートのみ許可して、他のポートをすべて遮断します。iptablesで保護されているので、Oracleポートへの外部アクセスは拒否されています。しかし、Oracleを全世界に公開してしまう危険性を少しでも下げるため、Vultr側のfirewallでも防御しておきます。

これ以降は、リモートから"linuser"でログインして、"sudo -s"で作業できます。

### 後の作業に必要なパッケージのインストール

後の作業で必要になるパッケージをインストールしておきます。

```
[root@vultr ~]# yum -y install unzip
    ：
[root@vultr ~]#
```

### dockerのインストール

dockerをインストールします。これには、以下の情報を参考にしています。むしろそのままです。
https://qiita.com/inakadegaebal/items/be9fecce813cebec5986

```
[root@vultr ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@vultr ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
[root@vultr ~]# yum makecache fast
[root@vultr ~]# yum -y install docker-ce
[root@vultr ~]# systemctl start docker
[root@vultr ~]# systemctl enable docker
[root@vultr ~]#
```

### 作業用アカウントへのdocker使用許可

```
[root@vultr ~]# usermod -aG docker linuser
[root@vultr ~]#
```

これ以降は、作業用アカウントで作業可能です。但し、"sudo -s"から"exit"で戻ってきただけではだめです。"usermod"の効果が反映されていません。その状況は"id"で確認できます。

```
[root@vultr linuser]# exit
[linuser@vultr ~]$ id
uid=1000(linuser) gid=1000(linuser) groups=1000(linuser)
[linuser@vultr ~]$
```

見てのとおり、dockerグループに所属していません。そのため、一度ログインしなおします。再ログイン後は"docker"グループに所属していることが確認できます。

```
[linuser@vultr ~]$ id
uid=1000(linuser) gid=1000(linuser) groups=1000(linuser),994(docker)
[linuser@vultr ~]$
```

## dockerイメージ作成

### 作業用ディレクトリの作成

作業用ディレクトリを作成し、作業用ディレクトリに移動します。

```
[linuser@vultr ~]$ mkdir -p tmp/xe
[linuser@vultr ~]$ pushd tmp/xe
~/tmp/xe ~
[linuser@vultr xe]$
```

### Oracle RPMの入手とファイル配置

[Oracleの公式サイト](https://www.oracle.com/database/technologies/xe-downloads.html)からLinux用のOracle RPMをダウンロードします。

ダウンロードされたファイル"oracle-database-xe-18c-1.0-1.x86_64.rpm"を、上記作業ディレクトリ"~/tmp/xe"に配置します。

### Dockerfileの入手

参考サイトではgitを使用しています。gitを使うまでもないので、[リポジトリ](https://github.com/oracle/docker-images.git)からZIPで落とすことにします。

```
[linuser@vultr xe]$ curl -s https://github.com/oracle/docker-images/archive/master.zip | awk 'BEGIN {FS="\""} {print $2}' | xargs curl -s -o docker-images-master.zip
[linuser@vultr xe]$ unzip -j docker-images-master.zip 'docker-images-master/OracleDatabase/SingleInstance/dockerfiles/18.4.0/*'
Archive:  docker-images-master.zip
7e03e466934753bc547c1919729702e5f33e4eba
  inflating: Dockerfile.xe
  inflating: checkDBStatus.sh
  inflating: checkSpace.sh
  inflating: oracle-xe-18c.conf
  inflating: runOracle.sh
  inflating: setPassword.sh
[linuser@vultr xe]$
```

### docker build

docker buildします。この処理は、Vultrの55GBプランのスペックでおよそ15分かかります。途中"Loaded plugins: ovl"と表示されてしばらく止まってしまいます。気長に待つと進むはずです。

```
[linuser@vultr xe]$ docker build -t oracle/database:18.4.0-xe -f Dockerfile.xe .
Sending build context to Docker daemon  2.577GB
    ：
[linuser@vultr xe]$
```

途中で以下のメッセージが表示されます。後で必要になるかもしれないので書き留めておくことにします。

```
    :
[INFO] Executing post installation scripts...
[INFO] Oracle home installed successfully and ready to be configured.
To configure Oracle Database XE, optionally modify the parameters in '/etc/sysconfig/oracle-xe-18c.conf' and then execute '/etc/init.d/oracle-xe-18c configure' as root.
    :
```

さて、作成されたイメージは以下のようになっています。

```
[linuser@vultr xe]$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
oracle/database     18.4.0-xe           f8983d56624b        About a minute ago   6GB
oraclelinux         7-slim              fd84774952b5        4 weeks ago          118MB
[linuser@vultr xe]$
```

## dockerコンテナ起動

コンテナ起動です。

```
[linuser@vultr xe]$ docker run -itd --name oracle18c -p 1521:1521 -p 5500:5500 -e 'TZ=JST-9' oracle/database:18.4.0-xe
2c8716c6bda6dda7f49e38cebb6b3ae2c52d625b5ebb9d2afcabc8f9b25a5507
[linuser@vultr xe]$ ss -lntp
State      Recv-Q Send-Q                                                      Local Address:Port                                                                     Peer Address:Port
LISTEN     0      128                                                                  [::]:5500                                                                             [::]:*
LISTEN     0      128                                                                  [::]:1521                                                                             [::]:*
    : sshd分を省いて表示しています
[linuser@vultr xe]$
```

2020/04/14追記 : SYSDATEが9時間ずれる問題を解消するために"-e 'TZ=JST-9'"を追加

## Oracle起動待ち

どうやらコンテナ起動直後のOracleは忙しいようです。Oracleのログを確認しながら少し待ちます。

起動しない、接続できないからと焦ってインストールしなおしても直りません。Oracleが起動しきるまで待つのが重要です。

```
[linuser@vultr xe]$ docker exec oracle18c /bin/bash -c 'tail -n 1000 -f /opt/oracle/diag/rdbms/xe/XE/trace/alert_XE.log'
    ：
alter pluggable database all close immediate
Completed: alter pluggable database all close immediate
    ：
Instance shutdown complete (OS id: 2066)
    ：
Adjusting the requested value of parameter parallel_max_servers
from 0 to 1 due to running in CDB mode
Starting ORACLE instance (normal) (OS id: 2288)
    ：
XEPDB1(3):Successfully created internal service XEPDB1 at open
***************************************************************
Post plug operations are now complete.
Pluggable database XEPDB1 with pdb id - 3 is now marked as NEW.
****************************************************************
    ：
ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE
Completed: ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE
```

コンテナ起動後、約15分かけて、"ALTER PLUGGABLE DATABASE XEPDB1 SAVE STATE"と表示されました。

これ以降、5分ほどかけても新しいログが表示されません。これで起動処理は終わったようです。

## パッケージインストール

ベースになっている"Oracle Linux 7.7"には、あまりパッケージが入っていません。そのため、使いそうなパッケージを入れておきます。

```
[linuser@vultr xe]$ docker exec oracle18c yum -y install vim less locate
    ：
[linuser@vultr xe]$
```

## パスワード設定

dockerを使用した際の初期パスワードはどうもわかりませんでした。そのため、再設定します。

[インストレーションガイド](https://docs.oracle.com/cd/E96517_01/xeinw/installing-oracle-database-xe.html)では"/etc/init.d/oracle-xe-18c configure"で設定するらしいです。しかし、dockerでのインストールだと既に設定されているらしく、以下のようになります。

```
[linuser@vultr xe]$ docker exec oracle18c /etc/init.d/oracle-xe-18c configure
Oracle Database instance XE is already configured.
[linuser@vultr xe]$
```

今回はテスト環境ということもあり、過去のバージョンで"SYSTEM"の初期パスワードに使われていた"MANAGER"を設定しています。本番では適切につけるべきです。

sqlplusをOracleユーザーで実行するのが重要なようです。"docker exec"の引数に"-u oracle"をつけてsqlplusを呼び出します。

```
[linuser@vultr xe]$ docker exec -it -u oracle oracle18c /opt/oracle/product/18c/dbhomeXE/bin/sqlplus / as sysdba

SQL*Plus: Release 18.0.0.0.0 - Production on Fri Apr 10 15:55:27 2020
Version 18.4.0.0.0

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


Connected to:
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

SQL> ALTER USER SYS IDENTIFIED BY MANAGER;

User altered.

SQL> ALTER USER SYSTEM IDENTIFIED BY MANAGER;

User altered.

SQL> QUIT
Disconnected from Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0
[linuser@vultr xe]$
```

## 動作確認

### 接続確認：ローカル

ローカルでの接続確認は、パスワード設定のタイミングで済んでしまいました。

### 接続確認：リモート

SSHトンネル越しに以下の接続ができることを確認します。

* SYS/MANAGER@127.0.0.1/XE AS SYSDBA
* SYSTEM/MANAGER@127.0.0.1/XE
* SYSTEM/MANAGER@127.0.0.1/XEPDB1

前回構築した11gでは、サービス名は"XE"でした。18c、12c以降では、マルチテナント・コンテナ・データベースの考えがあります。そのため、サービス名には"XE"と"XEPDB1"を指定しています。

また、外部からポート番号1521に直接接続できないことも確認します。確認手順は省略します。

# SQL結果

環境まわりのSQL実行結果を記載しておきます。

```
SELECT NAME FROM V$PDBS;

NAME
--------------------------------------------------------------------------------
PDB$SEED
XEPDB1
```

```
SELECT BANNER_FULL FROM V$VERSION;

BANNER_FULL
--------------------------------------------------------------------------------
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0
```

# 前に作った記事で確認した11gの挙動は、18cではどうなったか

前に作った記事"[Oracle BINARY_INTEGER型の引数を持つPL/SQLプログラムの挙動](https://qiita.com/szly/items/25edb7a64d1fcec105cb)"と"[Oracle INTEGER型の引数を持つPL/SQLプログラムの挙動](https://qiita.com/szly/items/c1762e0d61175499d175)"は、18cでも同じ動きでした。

# 感想

構築手順は極めて簡単でした。本質的には、"関連ファイルを作業ディレクトリに配置"、"docker build"、"docker run"だけです。

手順も大体わかったので、VirtualBoxでも一度作ってみようと思います。今の端末スペックで行けるだろうか。

Vultr上にセットアップしたOracle 18cの環境、VultrのSnapshot機能を使用することで追加費用なしで残しておくことができる、はずなのですがうまくいきません。Snapshotから復元したところ、外部からVPSにSSH接続できません。

ネットで検索しても"新しいIPアドレスにネットワーク設定を変えないといけない"と出てきます。しかしDHCPなので自動的に新しいIPアドレスは割り当たっているのです。そもそもVPSから外への通信は可能なのです。つまり、戻りのパケットはちゃんと外からVPSまで返ってくるのです。そうするとネットワーク設定は間違っていなさそうに思います。しかし、外から中への通信がなぜか通りません。

現象から考えるとiptablesかVultrのfirewallが怪しいところです。しかし、設定を見る限りよさそうに思います。復元がうまくいけば、使う時だけ復元というお手軽セットアップ可能な環境なのに。

とはいえ、一から作るとしても、インターネットに繋がる環境、1時間程度のセットアップ時間、数円程度の費用さえあれば、いつでもOracleを動かせられることがわかりました。