DOCKER で ORACLE DATABASE 12C を起動して PDB に接続するまで

接続には IntelliJ IDEA のプラグイン DBNavigator を使って接続します。

## Docker の起動まで

Docker Hub で "Oracle Database Enterprise Edition (Tue Jul 02 2019)" を探してイメージを取得します。
Oracle Database Server 12c R2 が取得できます。

Docker image に Oracle が追加されます。

```
% docker image ls
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE 
store/oracle/database-enterprise   12.2.0.1            12a359cd0528        23 months ago       3.44GB
```

そして、次のコマンドで docker を起動します。

```sh
docker run -it --name oracle-db -p 1521:1521 -p 5500:5500 store/oracle/database-enterprise:12.2.0.1 
```

## Oracle PDB への接続準備

次のコマンドを実行し、 SQLPLUS を起動します。

```sh
docker exec -it $CONTAINER_ID bash -c "source /home/oracle/.bashrc; sqlplus /nolog"   
```

```
# ORCLCDB に接続します。
## sys ユーザ のパスワードは Oradoc_db1 で、 sysdba として接続します。
SQL> conn sys/Oradoc_db1@ORCLCDB as sysdba

# PDB のセッションに変更します。
SQL> alter session set container=ORCLPDB1;

# ユーザを作成します。
SQL> create user developer identified by developer;

# 接続権限をつけます。
SQL> grant create session to developer;
```

## 接続設定確認

接続する場合はサービス名を確認します。
次のコマンドで、 Docker 内 の bash を使います。

```sh
docker exec -it  bash -c "source /home/oracle/.bashrc; bash"   
```

`lsnrctl status` を実行します。

```
[oracle@3fda365c7b37 /]$ lsnrctl status

LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 28-JUL-2019 01:43:37

Copyright (c) 1991, 2016, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1521)))
STATUS of the LISTENER
------------------------
Alias                     LISTENER
Version                   TNSLSNR for Linux: Version 12.2.0.1.0 - Production
Start Date                28-JUL-2019 01:43:11
Uptime                    0 days 0 hr. 0 min. 26 sec
Trace Level               off
Security                  ON: Local OS Authentication
SNMP                      OFF
Listener Parameter File   /u01/app/oracle/product/12.2.0/dbhome_1/admin/ORCLCDB/listener.ora
Listener Log File         /u01/app/oracle/diag/tnslsnr/3fda365c7b37/listener/alert/log.xml
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=3fda365c7b37)(PORT=5500))(Security=(my_wallet_directory=/u01/app/oracle/product/12.2.0/dbhome_1/admin/ORCLCDB/xdb_wallet))(Presentation=HTTP)(Session=RAW))
Services Summary...
Service "8eb4210da4b50113e053020011ac5c30.localdomain" has 1 instance(s).
  Instance "ORCLCDB", status READY, has 1 handler(s) for this service...
Service "ORCLCDB.localdomain" has 1 instance(s).
  Instance "ORCLCDB", status READY, has 1 handler(s) for this service...
Service "ORCLCDBXDB.localdomain" has 1 instance(s).
  Instance "ORCLCDB", status READY, has 1 handler(s) for this service...
Service "orclpdb1.localdomain" has 1 instance(s).
  Instance "ORCLCDB", status READY, has 1 handler(s) for this service...
The command completed successfully
```

下から3行目に `orclpdb1.localdomain` と書かれているのがわかります。
このサービス名を使ってデータベースに接続します。

これは Docker の Docker Image Documentation に書かれている次の記述にあたります。 `SERVICE_NAME` に `ORCLPDB1.localdomain` とありますね。

```
ORCLCDB=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<ip-address>)(PORT=<mapped>))
    (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCLCDB.localdomain)))
ORCLPDB1=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<ip-address> of host)(PORT=<mapped>))
    (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCLPDB1.localdomain)))
```

DB Navigator の画面で、 次の様に記述して "Test Connection" ボタン をクリックします。

| Name | Value |
|:--|:--|
| Host | localhost |
| Database | orclpdb1.localdomain (Service name) |
| User | developer |
| Password | developer |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25846/ce550d63-ebdc-653a-4891-743092be75e4.png)

接続に成功します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25846/9e19237f-45bf-549e-86a0-e524c0a947ea.png)

### Docker 内部の SQL*Plus から接続する場合

```
conn developer/developer@127.0.0.1/orclpdb1.localdomain   
```

## その他権限設定 (必要があれば)

```
# テーブル作成に必要
SQL> grant create table to developer;
# シーケンス作成に必要
SQL> grant create sequence to developer;
# INSERT 文 実行 に必要
SQL> alter user developer quota unlimited on USERS;

```