Dockerを使ってDigitalOceanにShinyアプリを公開する

こんにちは。冷やし中華を今年になって3回食べているのですが、友人は4回食べたそうです。

先日作成した「確率分布を動かして遊ぶShinyアプリ」ですが、 おかげさまでけっこうな数のかたに見ていただいているようです。 たいへん嬉しいのですが、ShinyApps.ioに公開しているため、 すぐに「THIS APPLICATION IS CURRENTLY UNAVAILABLE」となってしまいます。

せっかく紹介していただける機会も多いので、このたびDigitalOceanで公開することにいたしました。 こちらです↓

http://statdist.ksmzn.com/

前のURLでも見られるようにしておくつもりなので、 今後はお好きな方をごらんください。

ここからが本題です。 公開するにあたり、勉強がてらDockerを使ってみました。 ここでは、その作業手順を記しておきます。

DigitalOceanでサーバ作成

これに関してはメインではないので触れません。 僕はこちらのブログを参考にしました。

さくらのVPSからDigitalOceanへ移転

大事なのは、 Docker入りImage を選択することですね。

ちなみに、こちらのリンクからサインアップしていただけると お互いにメリットがあります。 https://www.digitalocean.com/?refcode=6dbd71c2251f

スワップを増やす

ワナがあります。このままの状態だと、メモリ不足でパッケージがインストールできないという事態に陥ります。 なので、こちらの記事を上から実行し、Ubuntuスワップ領域を増やしましょう。

How To Add Swap on Ubuntu 12.04 https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-12-04

Shiny用コンテナの作成

Dockerfileの作成

もうShinyアプリは完成している前提とします。

ありがたいことに、ShinyServerがインストール済のDockerイメージが公開されているので、 そちらを使わせていただきましょう。 https://registry.hub.docker.com/u/rocker/shiny/
↑のGithubリポジトリ

上記のrocker/shinyイメージだけでもShinyは動かせるのですが、 このイメージはRのパッケージが「Shiny」「rmarkdown」しかインストールされていません。

なので、rocker/shinyイメージをもとに、 自分のアプリに合わせたDockerfileを作成しましょう。

私のDockerfileは以下のようになっています。

FROM rocker/shiny:latest

RUN R -e "install.packages(c('shinydashboard', 'hypergeo'), repos='http://cran.rstudio.com/')"

COPY  /ShinyDistributionsApp/ /srv/shiny-server/

CMD exec shiny-server >> /var/log/shiny-server.log 2>&1

FROM 句でrocker/shinyを指定し、

RUN句で僕のアプリに必要な'shinydashboard'と'hypergeo'パッケージをインストールしています。 そして、COPY句でShinyアプリのソースをコピーし、CMD句でshinyを実行しています。単純ですね。

ビルド、そして実行

Dockerfileができたらビルドします。

DegitalOcean内にログインし、適当な名前をつけてビルド。

sudo docker build -t yourname/shiny-yourapp:latest .

初回は時間がかかります。 ビルドが完了したら、-d オプションをつけ、バックグラウンドで実行します。 rocker/shinyは、デフォルトでは3838ポートをEXPOSEしているようです。

sudo docker run -d -p 80:3838 yourname/shiny-yourapp:latest

これでバックグラウンドで実行されているので、 自分のドメインIPアドレスをブラウザに入力してみましょう。 アプリが動いているはずです。

ちなみに、大量アクセスが来た場合のことを何も考えていません。 おそらく、こちらのスライドのような対処が必要となることでしょう。

このスライドにおける方法①を試す場合、 Docker-Composeを使ってShinyとNginxのコンテナを立てることで実現可能ではないかと目論んでいます。 時期がきたら試してみます。

以上です。えんじょい。

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)

Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)