以前にも似た記事を書きましたが、最近はOracleのDockerfileもちゃんとしてきた(?)と聞いており機会があったので使ってみました。
以前の記事とOracleの公式docker-images
Docker上にOracle 11g XEを立てた - メンチカツには醤油でしょ!!
Docker上のOracleで初期化処理したい - メンチカツには醤油でしょ!!
github.com
手順
公式のoracle-docker-imagesをcloneします。
> git clone git@github.com:oracle/docker-images.git oracle-docker-images > cd oracle-docker-images/OracleDatabase/SingleInstance/dockerfiles/
シェルしか入っていないのでgit bashで実行します。
$ ./buildDockerImage.sh -v 11.2.0.2 Checking if required packages are present and valid... md5sum: oracle-xe-11.2.0-1.0.x86_64.rpm.zip: No such file or directory oracle-xe-11.2.0-1.0.x86_64.rpm.zip: FAILED open or read md5sum: WARNING: 1 listed file could not be read MD5 for required packages to build this image did not match! Make sure to download missing files in folder 11.2.0.2.
最近のバージョンだとこんな感じ?
$ ./buildDockerImage.sh -v 11.2.0.2 Ignored MD5 sum, 'md5sum' command not available. ========================== (略) ========================== Building image 'oracle/database:11.2.0.2-xe' ... Sending build context to Docker daemon 19.97kB Step 1/10 : FROM oraclelinux:7-slim 7-slim: Pulling from library/oraclelinux 4040fe120662: Pull complete Digest: sha256:fc684f5bbd1e46cfa28f56a0340026bca640d6188ee79ef36ab2d58d41636131 Status: Downloaded newer image for oraclelinux:7-slim ---> 9870bebfb1d5 Step 2/10 : MAINTAINER Gerald Venzl >gerald.venzl@oracle.com< ---> Running in a71d7d09ec46 Removing intermediate container a71d7d09ec46 ---> 8fbfe858e6a4 Step 3/10 : ENV ORACLE_BASE=/u01/app/oracle ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe ORACLE_SID=XE INSTALL_FILE_1="oracle-xe-11.2.0-1.0.x86_64.rpm.zip" INSTALL_DIR="$HOME/install" CONFIG_RSP="xe.rsp" RUN_FILE="runOracle.sh" PWD_FILE="setPassword.sh" CHECK_DB_FILE="checkDBStatus.sh" ---> Running in 89c3b8b9903a Removing intermediate container 89c3b8b9903a ---> 9eee281e0381 Step 4/10 : ENV PATH=$ORACLE_HOME/bin:$PATH ---> Running in e54a5c7a3b7e Removing intermediate container e54a5c7a3b7e ---> 4fc9ca630118 Step 5/10 : COPY $INSTALL_FILE_1 $CONFIG_RSP $RUN_FILE $PWD_FILE $CHECK_DB_FILE $INSTALL_DIR/ COPY failed: stat /var/lib/docker/tmp/docker-builder439774754/oracle-xe-11.2.0-1.0.x86_64.rpm.zip: no such file or directory ERROR: Oracle Database Docker Image was NOT successfully created. ERROR: Check the output and correct any reported problems with the docker build operation.
oracle-xe-11.2.0-1.0.x86_64.rpm.zip がないと言っていますね。
そうなんです、インストールイメージはOTNからライセンス条項に同意のうえダウンロードする必要があるんですね。下記のリンクより Oracle Database Express Edition 11g Release 2 for Linux x64 をダウンロードして、シェルが参照しているディレクトリdocker-images/OracleDatabase/dockerfiles/11.2.0.2/に配置します。
Oracle Database Express Edition 11g Release 2のダウンロード
↓url変更になっていました。
Oracle Database Express Edition 11g Release 2 | Oracle 日本
※ Windows環境でも、Docker上にOracleを構築するので、Linux版をダウンロードします。
※ 最近のbuildDockerImage.sh ではExpress Editionを表す -x を指定する必要があります。(2020/05/08追記)
※ シェルのファイル名が変更になっていたので追従(buildDockerImage.sh⇒buildContainerImage.sh)(2021/06/08 追記)
$ ./buildContainerImage.sh -v 11.2.0.2 -x Checking if required packages are present and valid... oracle-xe-11.2.0-1.0.x86_64.rpm.zip: OK ========================== DOCKER info: (かなり長いので中略) Successfully built 78db1a697c0e Successfully tagged oracle/database:11.2.0.2-xe SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories. 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 117 seconds.
はい、無事に成功しました。
ここで次のようなエラーが出る場合は、Docker DesktopでWindowsコンテナで動かしている可能性がありますので、タスクトレイにあるDockerアイコンを右クリックしてSwitch to Linux Containers...をクリックして、DockerコンテナをLinuxで動作させるか、もしくは、ここを参考に、experimentalをtrueにしてみましょう。
========================== Building image 'oracle/database:11.2.0.2-xe' ... Sending build context to Docker daemon 315.9MB Step 1/8 : FROM oraclelinux:7-slim 7-slim: Pulling from library/oraclelinux no matching manifest for windows/amd64 10.0.19042 in the manifest list entries ERROR: Oracle Database container image was NOT successfully created. ERROR: Check the output and correct any reported problems with the build operation.
確認
> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
oracle/database 11.2.0.2-xe 78db1a697c0e 2 hours ago 1.13GB
oraclelinux 7-slim 9870bebfb1d5 2 weeks ago 118MB
・・・
さて実行みましょう
> docker run oracle/database:11.2.0.2-xe
Error: The container doesn't have enough memory allocated.
A database XE container needs at least 1 GB of shared memory (/dev/shm).
You currently only have 64 MB allocated to the container.
これはコンテナのメモリが1GB無いから出るエラーですので、メモリ1GBを指定してあげましょう。(--shm-size=1gを追加します)
> docker run -d --name my-oracle --shm-size=1g -p 1521:1521 -p 8080:8080 -e ORACLE_PWD=MyOraclePassword oracle/database:11.2.0.2-xe
これで立ち上がったと思います。
試しに接続してみるには、ホストPCのsqlplusを使ってもいいですし、コンテナ内のsqlplusを呼び出す方法もあります。
> sqlplus sys/MyOraclePassword@localhost:1521/XE as sysdba > docker exec -it my-oracle sqlplus sys/MyOraclePassword@XE as sysdba
初期化SQLや初期データの投入
初期化スクリプト・初期化SQL・初期データなどの入ったディレクトリをボリュームマウントします。
ディレクトリ内の拡張子 .sh または .sql については自動で実行されます。実行順をより明示的にするために 01_alter_user.sql など頭に数値を付ける命名が推奨されています。
また、shやsqlファイルは、utf-8のLFで保存しておくとより安心でしょう。
> docker run -d --name my-oracle --shm-size=1g -p 1521:1521 -p 8080:8080 -e ORACLE_PWD=MyOraclePassword -e TZ="Asia/Tokyo" -v C:\my-docker\oracle\startup:/docker-entrypoint-initdb.d/startup -v C:\my-docker\oracle\oradata:/u01/app/oracle/oradata oracle/database:11.2.0.2-xe
相対パス指定だとうまくいかないことがあります。
こんなメッセージが出ますので絶対パスで指定することが推奨されています。
docker: Error response from daemon: create 【ファイルパス】: "【ファイルパス】" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
See 'docker run --help'.
ファイルだけ指定するのもダメです
> docker run -d --name my-oracle --shm-size=1g -v C:\my-docker\oracle\startup\01_alter_user.sql:/docker-entrypoint-initdb.d/startup oracle/database:11.2.0.2-xe 0e735b3b58b3d9067560fa9fec41f67d2411c3fea7a481f2e8eafc41cbae3c27 docker: Error response from daemon: oci runtime error: container_linux.go:265: starting container process caused "process_linux.go:368: container init caused \"rootfs_linux.go:57: mounting \\\"/C/my-docker/oracle\startup/01_alter_user.sql\\\" to rootfs \\\"/var/lib/docker/aufs/mnt/d898bc13bb479bbcb411fb45c242fbfcac0bbeaeacafaa3054cb1025e87c1af8\\\" at \\\"/var/lib/docker/aufs/mnt/d898bc13bb479bbcb411fb45c242fbfcac0bbeaeacafaa3054cb1025e87c1af8/u01/app/oracle/scripts/startup\\\" caused \\\"not a directory\\\"\"" : Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type.
startupディレクトリ配下には 01_alter_user.sql などのようなファイルに下記のようにsqlを記述しておけば、コンテナ始動時に実行されます。
-- ユーザー作成
CREATE USER MY_ORACLE_USER IDENTIFIED BY "MyUserPassword" DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
また、下記のようにimpを実行するシェルを 03_imp.sh のように同じディレクトリにおいておけばdocker runするだけでDB/ユーザー/データが手に入って便利かと思います。
#!/bin/bash imp MY_ORACLE_USER/MyUserPassword@XE file=/docker-entrypoint-initdb.d/startup/02_my_data.dmp full=y
参考
Oracle Database on Docker · docker-images/README.md at master · oracle/docker-images · GitHub