はじめに
統計解析向けに使われるR言語をWebアプリ化できるShinyというパッケージがあります。
この課題を解決できるShinyProxy
というものを触ってみましたので、記事にしました。
参考
Shinyの課題
参考に紹介したQiitaの記事から引用します。
OSSのShiny Serverでは、1つのShinyappが 1 processで動くため、複数人のユーザでアクセスすると、急に動きがもっさりしがちです。例えば、ユーザA、Bの順でアクセスして、データをロードしはじめると、ユーザAの処理が終わるまで、ユーザBは待たないといけないので、待っている間ストレスがかかります
ShinyProxyでの解決
ShinyProxyでは以下のようなことを行って、先の課題を解決しています。
- Shinyのアプリをdockerイメージで用意します
- 上記イメージを使うよう、ShinyProxyで設定します
- ShinyProxyでユーザを認証し、ユーザごとにコンテナを起動してくれます
余談:その他の解法
ShinyProxyは自前でサーバを運用・管理する必要がありますが、以下のサービスを使えばサーバの管理も不要のようです。
認証機能込みのSTANDARDプランだと、月額16,000円くらいです。サーバ管理から解放されることを考えるとよい値段と思います。
やってみた
Cloud9のインスタンスは、コンテナを使うのでt3.small
にしました。
Standaloneモードで実行
Standaloneモードは、ホスト上でShinyProxyを動かすものになります。
まず公式のGetting Startedに従ってやっていきます。
Javaの確認です。
$ java -version
openjdk version "11.0.18" 2023-01-17 LTS
OpenJDK Runtime Environment Corretto-11.0.18.10.1 (build 11.0.18+10-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.18.10.1 (build 11.0.18+10-LTS, mixed mode)
DockerはCloud9だとインストール済みなので、Docker startup optionsに続きます。
こちらは、以下のサイトを参考にしました。
# 新規作成
$ mkdir /etc/systemd/system/docker.service.d
$ sudo vi /etc/systemd/system/docker.service.d/override.conf
# 以下の内容を追加
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:// -D -H tcp://127.0.0.1:2375
# 以下のコマンドを実行
$ sudo systemctl enable docker.service
$ sudo systemctl status docker.service
$ sudo systemctl start docker.service
$ sudo systemctl stop docker.service
$ sudo systemctl restart docker.service
$ sudo docker version
ShinyProxyを実行
ShinyProxyを実行するには、rpmファイルをダウンロードしてインストールする方法と、jarファイルを実行する方法があります。
$ wget https://github.com/openanalytics/shinyproxy/releases/download/v3.0.1/shinyproxy-3.0.1.jar
$ java -jar shinyproxy-3.0.1.jar
$ https://www.shinyproxy.io/downloads/shinyproxy_3.0.1_x86_64.rpm
$ sudo yum localinstall ./shinyproxy_3.0.1_x86_64.rpm
$ sudo systemctl enable shinyproxy
$ sudo systemctl start shinyproxy
$ sudo systemctl status shinyproxy
# 止める場合
$ sudo systemctl status shinyproxy
一旦、CTRL-Cで止めます。
デモ用ShinyアプリのイメージをPULL
$ docker pull openanalytics/shinyproxy-demo
結構大きめでした。
$ sudo docker images | grep shinyproxy
openanalytics/shinyproxy-demo latest a4ad82a764ab 11 months ago 1.35GB
config
以下の公式を参考にしていきました。
jarでの実行時は、jarと同じフォルダに、application.yml
を配置します。
touch application.yml
インストールでの場合は/etc/shinyproxy/application.yml
になります。
authentication: simple
だけ修正します。
proxy:
title: Open Analytics Shiny Proxy
logo-url: https://www.openanalytics.eu/shinyproxy/logo.png
landing-page: /
heartbeat-rate: 10000
heartbeat-timeout: 60000
port: 8080
authentication: simple
admin-groups: scientists
# Example: 'simple' authentication configuration
users:
- name: jack
password: password
groups: scientists
- name: jeff
password: password
groups: mathematicians
# Example: 'ldap' authentication configuration
ldap:
url: ldap://ldap.forumsys.com:389/dc=example,dc=com
user-dn-pattern: uid={0}
group-search-base:
group-search-filter: (uniqueMember={0})
manager-dn: cn=read-only-admin,dc=example,dc=com
manager-password: password
# Docker configuration
docker:
cert-path: /home/none
url: http://localhost:2375
port-range-start: 20000
specs:
- id: 01_hello
display-name: Hello Application
description: Application which demonstrates the basics of a Shiny app
container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
container-image: openanalytics/shinyproxy-demo
access-groups: [scientists, mathematicians]
- id: 06_tabsets
container-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
container-image: openanalytics/shinyproxy-demo
access-groups: scientists
logging:
file:
name: shinyproxy.log
再度、ShinyProxyを実行します。
$ java -jar shinyproxy-3.0.1.jar
$ sudo systemctl restart shinyproxy
プレビューは、以下のボタンを押してブラウザでの表示で行います。内部のプレビューではログイン後にエラーになりました。
application.yaml
で設定したユーザでログインします。
起動するまでの待ち画面が表示されます。
起動後は、以下の画面になりました。
アプリの選択前後でコンテナが増えていることがわかります。
# アプリを選択する前
$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 選択した後
$ docker ps --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a4a01ca81f2b3e0f73e7cfc1bbf4f7269ee4b5c82679e3594540104763801089 openanalytics/shinyproxy-demo "R -e shinyproxy::run_01_hello()" About a minute ago Up About a minute 0.0.0.0:20000->3838/tcp nervous_moser
Containerizedモード
Containerizedモードは、ShinyProxy自体もコンテナで動かすものになります。
公式の以下の通りにやってみます。
新しいディレクトリを作り、そちらで行っていきます。
$ mkdir test-containerized && cd test-containerized
# Dockerfileを作成し、上記GitHubの内容をコピーします
$ touch Dockerfile
# application.ymlも同様にコピーします
$ touch application.yml
# Dockerネットワークを作ります
$ docker network create sp-example-net
# 確認
$ docker network ls
# build
$ docker build . -t shinyproxy-example
# run
$ docker run -v /var/run/docker.sock:/var/run/docker.sock:ro --group-add $(getent group docker | cut -d: -f3) --net sp-example-net -p 8080:8080 shinyproxy-example
Standaloneの時と同様に、ログインしてアプリが実行できました。
自作のShinyアプリをイメージにして使う方法
今まではShinyのアプリが既にdockerイメージになっていましたが、今度はShinyアプリをdockerイメージにする方法も行ってみました。
以下の2つを参考にしました。
$ mkdir test-apps && cd test-apps
# テンプレートをクローン
$ git clone https://github.com/openanalytics/shinyproxy-template.git
$ cd shinyproxy-template/
# Shinyアプリのイメージを作成
$ docker build -t openanalytics/shinyproxy-template .
$ cd ..
$ touch application.yml
最初に作ったapplication.yml
の、spec
のみ以下に差しかえます。
specs:
- id: euler
display-name: Euler's number
container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"]
container-image: openanalytics/shinyproxy-template
access-groups: scientists
Shinyproxyを実行します。
$ wget https://github.com/openanalytics/shinyproxy/releases/download/v3.0.1/shinyproxy-3.0.1.jar
$ java -jar shinyproxy-3.0.1.jar
おわりに
今回は統計解析のWebアプリの運用を楽にできるShinyProxyを紹介しました。
Cloud9上での実行でしたが、EC2でも同様の方法で動くと思われます。
どなたかのお役に立てれば幸いです。