【AWSでShiny】AMIを使ってAWS上に手っ取り早くShiny環境を作る。

AWS始めました。

種々やりたいことはあります。ありますが、取り急ぎ、Shinyで作ったアプリを社内向けに公開したい、という目的がございまして。ぶっちゃけ、Shiny serverを自前でインストールすれば済む話っちゃ話なのです。

www.randpy.tokyo

が、とりあえず的にShiny環境を作るのに、パブリックなAMIを使っちゃえば深く考えなくていいんじゃね?という発想でやってみました。非常に簡単なので、ほんとに手っ取り早くやるにはこれで十分かと。

前提条件

  • AWSアカウントを取得している
  • EC2インスタンスの作り方がわかっている
  • キーペアの作り方がわかっている
  • Putty等のSSH接続できるアプリをインストールしてある
  • linuxコマンドをある程度知っている

こんだけあれば十分でしょう。

AMIを使ったEC2インスタンスの作り方

RStudio Server Amazon Machine Image (AMI) - Louis Aslett

↑こちらのAMIを使わせてもらいます。

f:id:wanko_sato:20180325091547j:plain

ステップ1でAMIを選びます。このとき、”コミュニティAMI”を選択し、検索してください。検索文字列はAMIのIDにすると良いでしょう。

f:id:wanko_sato:20180325091802j:plain

インスタンスのタイプを選びます。とりあえず的にt2.microを選んであります。なんせ無料枠なので。。。使いたい要件に合わせてインスタンスタイプは選んだら良いです。
Rは特にメモリの消費量が激しいので、処理によってはメモリの大きいものが良いでしょうし、あるいは複数ユーザが同時にアクセスするのなら、CPUを増やす方が良いかもしれません。

それ以外の細かな設定はお好みで。

f:id:wanko_sato:20180325092044j:plain

で、セキュリティグループはこんな感じの設定になります。
SSHはマイIPにしておきます、念のため。HTTPは解放、Shiny serverはデフォルトでポート3838を使うように設定してあるので、カスタムTCPでポート3838を設定します。

で、キーペアを割り当ててインスタンスを立ち上げます。これで設定終了。

すぐにできること

このAMIにはRStudio server、Shiny server、Jupyter、Julia、CUDAがバンドルされています。特に面倒な設定なしに、インスタンスを立ち上げればすぐに使える状態になっています。
インスタンスが立ち上がったら、該当するインスタンスのパブリックIPにアクセスすると、

f:id:wanko_sato:20180325092614j:plain

こうなるはずです。すぐにRStudioが使える状態になっています。なお、デフォルトではユーザー名、パスワードともにrstudioになっています。パスワードの変更やユーザの追加はターミナルから行います。それは後述。

f:id:wanko_sato:20180325092809j:plain

http://(パブリックIP)/julia/

で上の画面になります。jupyterがすぐに使える状態になっています。jupyterの設定って意外に面倒なんですよね。。。なのですぐに使える状態になっているのは意外に便利です。
※今回はjupyter、juliaには言及しません。あくまでもRStudioとShinyのみです。

f:id:wanko_sato:20180325092934j:plain

http://(パブリックIP)/rstudio/

で上の画面になります。ちゃんとShiny serverが動いていれば、右のフレームの中にShinyっぽい画面が入っているはずです。ちなみにパブリックIPの後ろの”rstudio”はユーザ名になります。デフォルトではrstudioしかユーザがいませんが、ユーザを追加すると、rstudioの部分はそのユーザ名にすることができます。このあたりも後述します。

f:id:wanko_sato:20180325093731j:plain

さらに、

http://(パブリックIP):3838/rstudio/sample-apps/hello/

で上の画面のShiny appに直接アクセスできます。なぜこうなるかは、ディレクトリの構成を確認しないとわからないところなので、後述します。

詳細

というわけで、ブラウザからRStudio serverならびにShiny serverが立ち上がっていることが確認できました。次に、Puttyからインスタンスの中身を確認していくことにしましょう。

SSH接続

f:id:wanko_sato:20180325094332j:plain

Host NameにパブリックIPを入力し、

f:id:wanko_sato:20180325094407j:plain

プライベートキーのパスを設定したら、接続します。

f:id:wanko_sato:20180325094556j:plain

ログインIDはデフォルトでは"ubuntu"です。

f:id:wanko_sato:20180325094736j:plain

みてわかる通り、使用したAMIのOSはubuntuです。

構成を確認する

ログインした状態で

ls

とすると

NVIDIA_CUDA-8.0_Samples  RStudioAMI_0.2.1.tar.gz  ShinyApps

があります。あらかじめCUDAも入っているんです。いろいろすごいよ、これ。

cd /
ls

でルートディレクトリを見にいきますと、

bin   initrd.img                lib64       proc  srv  vmlinuz
boot  initrd.img.old            lost+found  root  sys  vmlinuz.old
dev   jupyterhub_cookie_secret  media       run   tmp
etc   jupyterhub.sqlite         mnt         sbin  usr
home  lib                       opt         snap  var

jupyterがはいっていたり、いろいろです。で、このなかで大事なのがhomeです。

cd home
ls

で確認すると、

rstudio  shiny  ubuntu

デフォルトでこの三種類のユーザが作られています。RStudioにログインしたのも、Shiny serverの確認をしたのも、このうちのrstudioなわけです。

cd rstudio
ls

としますと、

R  ShinyApps  Welcome.R

となっています。このうち、"ShinyApps"ディレクトリにShinyアプリを格納していきます。上記

http://(パブリックIP):3838/rstudio/

にアクセスしたとき、直接この"ShinyApps"ディレクトリにアクセスしているわけです。ちなみに、このShinyAppsディレクトリには

index.html  log  sample-apps

というファイルならびにディレクトリが入っています。上記URLでアクセスしたとき、このindex.htmlに直接アクセスしていた、ということなわけです。ちなみに、

less /etc/shiny-server/shiny-server.conf

デフォルトのShiny serverのconfigurationを見に行くと、

run_as shiny;
server {
  listen 3838;
  run_as :HOME_USER:;
  location / {
    user_dirs;
  }
}

このようになっています。これをいじるとアクセス先を変えたりポート番号を変えたりできます。が、あんまりいじると意味不明なことになってしまうので、今回はいじりません。

ユーザを追加する

すでに書いたように、このAMIのOSはubuntuです。したがって、ユーザの追加にはuseraddではなくadduserを使います。

qiita.com

理由はこちらにある通り、useraddだとhomeディレクトリ以下に新しいユーザのディレクトリが作られないからです。早速やってみましょう。

sudo adduser testuser

とします。なお、rootログインしているわけではないので、sudoが必要です。

Adding user `testuser' ...
Adding new group `testuser' (1003) ...
Adding new user `testuser' (1003) with group `testuser' ...
Creating home directory `/home/testuser' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:

となるので、任意のパスワードを入力します。

Retype new UNIX password:
passwd: password updated successfully
Changing the user information for testuser
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n]

パスワードをリタイプ、フルネームやルームナンバーは無視、最後にYを入れれば完了です。

ls /home

rstudio  shiny  testuser  ubuntu

testuserが追加されました。この状態ではtestuserのホームディレクトリには何もない状態です。が、RStudioにはログインすることができます。

f:id:wanko_sato:20180325101659j:plain

追加したユーザ名とパスワードでRStudioにログインし、terminalタブでpwdすると、testuserのホームディレクトリにいることがわかります。こんな風にユーザの追加は非常に簡単です。

ShinyAppsにシンボリックリンクを張る

さて、ユーザの追加ができたわけですが、これだけではいけません。追加したユーザのホームディレクトリは空っぽなので、Shinyアプリをこのユーザは利用できないからです。ならば他のユーザからアプリのコードをコピーしてくる?いやいや、そうするとコードを更新したとき、全ユーザのコードを更新しなければならなくなり、アプリのアップデートがものすごく手間になります。
そこで、rstudioを親ユーザとし、追加したユーザは子ユーザとして、rstudioのShinyAppsディレクトリにシンボリックリンクを張ってしまいます。こうすることで、コードを一元管理できるようになります。

cd /home/testuser
sudo ln -s /home/rstudio/ShinyApps/ ShinyApps
ll

これでrstudioのShinyAppsにシンボリックリンクを張ることができます。

drwxr-xr-x  5 testuser testuser 4096 Mar 25 01:23 ./
drwxr-xr-x  7 root     root     4096 Mar 25 01:09 ../
-rw-r--r--  1 testuser testuser  220 Mar 25 01:09 .bash_logout
-rw-r--r--  1 testuser testuser 3771 Mar 25 01:09 .bashrc
-rw-r--r--  1 testuser testuser  655 Mar 25 01:09 .profile
drwxr-xr-x  3 testuser testuser 4096 Mar 25 01:13 R/
drwxr-xr-x 12 testuser testuser 4096 Mar 25 01:13 .rstudio/
lrwxrwxrwx  1 root     root       24 Mar 25 01:23 ShinyApps -> /home/rstudio/ShinyApps//

llでみるとこんな感じ。所有者はrootになっていますので、気になるようでしたらchownで変更しといてください。
この状態で、

http://(パブリックIP):3838/testuser/

にアクセスし、下の画面が表示されれば成功です。

f:id:wanko_sato:20180325092934j:plain

とりあえずこれで複数ユーザにShinyアプリを公開する準備ができました。

まとめ

  • AMIを使うとShiny serverが簡単に立てられるよ
  • jupyterもバンドルされているのでいろいろ便利だよ
  • アプリの一元管理はちょっと工夫してね
  • Shinyでlinuxコマンドを使う場合はディレクトリとファイルの所有者とグループに注意してね

※最後のはご自身でRの挙動を確認してみてください。

いじょっ。