Chapter07 Docker For R × MySQL

はじめに

ここでは、RStudio ServerとMySQLのコンテナを起動し、Rとデータベースを接続した分析環境を構築します。RStudio Serverの環境構築には、rocker/tidyverseイメージを使用し、MySQLはmysql:8.0.20イメージを使用します。

全体図

ここでは、data_envというディレクトリを作成し、そこで作業を行います。最終的なディレクトリ構造は下記の通りです。docker-compose.ymlに各コンテナ情報をまとめて記述し、docker-compose upでコンテナを複数起動する方法もありますが、わかりやすさのためにここではdocker-compose.ymlを分けています。

➜ tree data_env
data_env
├── MySQL
│   ├── docker-compose.yml
│   ├── init
│   │   ├── 10_ddl.sql
│   │   ├── 20_data_load.sh
│   │   ├── data1.csv
│   │   └── data2.csv
│   └── var_lib_mysql
│       ├── #ib_16384_0.dblwr #コンテナ起動時に生成されるMySQLファイル
│       ├── #ib_16384_1.dblwr #コンテナ起動時に生成されるMySQLファイル
【略】
└── R
    ├── Dockerfile
    ├── docker-compose.yml
    └── working_dir

MySQLにはコンテナ起動時にcsvのデータがインサートされるようにしています。これはチャプター04のMySQLのコンテナ環境の構築で説明した内容どおりです。RStudio Serverのコンテナ環境についても、チャプター05のRのコンテナ環境の構築で説明した内容どおりです。では、各コンテナの内容を確認しておきます。

MySQLのコンテナ環境

再度、MySQLの環境について内容を確認しておきます。docker-compose.ymlの中身はこのようになっています。var_lib_mysqlディレクトリでデータを永続化し、initディレクトリで初回起動時にデータがインサートされるようにしています。ポートが13306なのは私のホスト環境にMySQLサーバーがあるので、ポートが衝突しないためです。

10_ddl.sqlでテーブルを定義して、20_data_load.shでデータをインポートしています。MySQL8を使うので、set global local_infile = 1;を忘れないようにします。

Rのコンテナ環境

再度、Rの環境について内容を確認しておきます。docker-compose.ymlの中身はこのようになっています。コンテナを起動した際に、RMySQLDBIなどのパッケージをインストールしたいので、build: .として、Dockerfileからビルドするようにしています。あとは、ワーキングディレクトリを作成しています。

Dockerfileの中身はこのようになっています。

コンテナの起動

それでは準備が整ったので、コンテナを起動していきます。まずはMySQLのコンテナを起動します。

コンテナが起動していることが確認できます。

データが入っているか確認しておきます。

問題なくデータもはいっているので、次はRStudio Serverのコンテナを起動します。

コンテナが起動していることが確認できます。

それではRStudio Server(http://localhost:8787/arrow-up-right)にアクセスします。IDとパスワードはrstudioです。下記のコマンドを実行してMySQLからデータを取得します。

ここで注意する必要があるのがhostの設定です。MySQLのコンテナはローカルホストで起動していますが、ローカルホストの設定をするとコネクションを構築できません。本来であればこれらのコンテナのネットワークを構築するべきかもしれませんが、ここではアドレスを直接Rスクリプトで指定する方法にしています。

Dockerネットワーク

1つのコンテナでは1つの機能を動かす構成にすると、コンテナ間の連携が必要になる場合があります。今回のように、MySQLとRStudio Serverの各コンテナを起動させ、MySQLのデータをRStudio Serverで取得するときなどです。コンテナ間通信を行う方法は、2つあります。

  • Dockerネットワークを作成し、コンテナ名で接続できるようにする

  • --linkオプションを使用する(レガシー機能なので非推奨)

デフォルトでbridgeというDockerネットワークがデフォルトで作成されています。bridgeは、DNS設定がされていないため名前解決ができず、コンテナ名を使用したコンテナ間通信ができません。その場合、コンテナ起動時に自動で割り当てられるプライベートIPアドレスを用いる方法で通信します。新規でDockerネットワークを作成すると、コンテナ名を使用してコンテナ間で通信ができます。docker network create <network name>でネットワークを作成できます。

現状ではデフォルトのネットワークであるbridgeの中にMySQLもRStudio Serverも含まれています。

RからMySQLにコネクションを構築するので、MySQLのネットワークを調べます。Gatewayにあるアドレスをコネクション構築時に使用する必要があります。

Gatewayの値を取得したければ、下記のようにすれば取得できます。

このように複数のコンテナを起動して、コンテナ間通信する場合にはネットワークの設定も必要なるので注意が必要ですね。

docker-compose upでコンテナを複数起動

docker-composeでコンテナを複数起動する方法に変更する方法をまとめておきます。さきほどのディレクトリdata_envディレクトリをコピーしてdata_env2ディレクトリを作成します。ディレクトリ構成は下記のとおりです。

まずは各コンテナを通信するためのネットワークdata_analysis_networkを作成します。

コネクションを作成する際のアドレスを確認しておきます。

それではdocker-compose.ymlを下記のように書き換えます。注意する点としては、各サービスの項目にnetworks: - data_analysis_networkが追加されている点と、コンテナの通信を利用するためのnetworks項目を最下部に追記した点です。

これで準備が整ったので、コンテナを起動します。

コンテナの状況を確認します。

コンテナがバックグラウンドで起動していることが確認できたので、http://localhost:8787/arrow-up-rightにアクセスします。data_analysis_networkのアドレスを使ってコネクションを作成します。

コンテナ間の通信もできていることが確認できました。使用後はコンテナを停止しておきます。

Last updated