GitHub Actionsを使ってshinyapp.ioへ自動デプロイ
背景
これまではRstudioで開発したShinyのアプリケーションをRstudioからデプロイしていました。しかしGitHubで管理するようになって、自動デプロイできた方が、サーバーに上がっているコードの管理の面からも効率が良いだろうと思い、今回の内容に至りました。
GitHub ActionsもDockerも使った経験のない私はいろいろと試行錯誤が必要だったので、その記録として解説していきます。
参考にしたサイト
以下の記事を参考に、自分に必要な範囲にコードを簡略化しています。
実現したいこと
GitHub Actionsを使ってmainブランチが更新されたタイミングで、shinyapp.ioに自動でデプロイする。
必要なファイル、階層
デプロイ作業に必要なファイルはauto_deploy.yml, Dockerfile, deploy.Rの三つです。コードは最後につけています。
あとはアップしたいファイルを用意してください。
./
├─ .github/
│ └─ workflows/
│ └─ auto_deploy.yml
├─ Dockerfile
├─ deploy.R
└─ (server.Rやui.Rなどshinyapp.ioに上げたいファイル)
GitHub Actions
処理の概要
まずはGitHub Actionsを用意します。自動デプロイ関連ではまずこれが動きます。
それぞれのコマンドの解説はGitHubのページを参照してください。
今回の例はmain
にコミットがあったときにデプロイされるようにしています。設定を変えることでプルリクエストのタイミングでもデプロイされるようにしたり、コミット名に指定の文字列を入っているときはデプロイしないようにするなどが可能です。
やっていることとしてはDockerを起動して、後述するDockerfileの内容を実行させているだけです。特徴としてはshinyapp.ioに接続するためのsecretを環境変数として渡しているところです。secretはあらかじめ取得しておく必要があります。username
にはshinyに登録したユーザー名、appname
にはデプロイしたいアプリケーション名を渡します。デプロイしたアプリケーションのURLはhttps://username.shinyapps.io/appname/
のようになります。
secretの取得
まずはshinyapp.ioにログインします。次にユーザー名のところからToken
へ進みます。
するとトークンの管理画面に移るので、Add Token
から新しいトークンを作成してください。次にshow
というボタンから詳細を確認します。そうしたらshow secret
を押して全て表示させます。ここでtoken
とsecret
の値が大事なので、控えてください(画像では消しています)。
secretの設定
ここからはGitHub上での設定になります。自動デプロイを実装したいリポジトリのSetting > Secrets and variables > Actions
に進みます。そうしたらNew repository secret
を押し、SHINYAPPS_TOKEN
として先ほどのtoken
を、SHINYAPPS_SECRET
としてsecret
を登録してください。値はシングルクオーテーションで囲んでください。
Dockerfile
処理の概要
次にGitHub Actionsで使うDockerfileの設定に移ります。DockerはGitHubで動かすので、自分の環境にDocker Desktopをインストールする必要はありません。
rockerの利用
R関連のコンテナを配布しているrockerというプロジェクトがあります。今回はここからshinyの基本的なパッケージが入っているrockerを取り込んでいます。rockerにはtidyverse環境も含んだコンテナなどもあるため、一覧のページから自分に合ったrockerを探してください。
関連ライブラリのインストール
次にライブラリを環境にインストールします。自分がアップロードしたいファイル内で使っているライブラリをインストールしてください。例としてdplyr, ggplot2を示しているようにスペース区切りで列挙していけば大丈夫です。また、rockerで既に対応してある分は不要です。rsconnect
はデプロイに使うため、どんなコードを上げるとしても必要です。
デプロイファイルの準備
残りのコードはデプロイ関連の処理をしています。まず、WORKDIR
でデプロイ用のファイルを入れておく新しいディレクトリを作成してそこに移動します。そうしないと元のワーキングディレクトリが全てアップされてしまうので、git関連のファイルも上げてしまい非効率的になります。そのあとCOPY
でデプロイするファイルをコピーしていきます。以前ファビコンの設定を紹介したので、それもアップするコードにしています。この時ディレクトリを新しく作る必要はありません。
デプロイの実行
最後にdeploy.R
を実行します。WORKDIR
でワーキングディレクトリを移動させているので、deploy.R
もCOPY
する必要があります。
deploy.R
最初に示したサイトでは、環境変数が取得できなかった時にエラーが出るようにチェック用の関数を用意しています。必要な方は参考にしてみてください。
ここで書かれている。setAccountInfo
はshinyapp.ioで見たものです。ここで環境変数を使わずにここにtokenなどを直書きしても動作はすると思います。ただし、このコードはGitHubに上がりますので、パブリックリポジトリがなら接続に必要な情報が公開され、誰でもアクセスできるようになってしまいます。やめましょう。
どのみちurlから分かってしまうので、私はusernameとappnameをDockerfileに入力してしまっていますが、これも本来ならsecretの設定で設定しておくべき項目でしょう。
まとめ
今回はGitHub Actionsを使ってshinyapp.ioに自動デプロイする方法を紹介しました。同じようにやれば任意のサーバーにアップすることができるでしょうし、deploy.Rの中は自由に書けるので、Rを使った何かしら処理もできてしまうと思います。
ちなみにGitHub Actionsは完全無料ではありません。今回のデプロイくらいであれば無料の範囲で収まると思いますが、より大きな規模の処理をさせる場合は料金体系を調べてみてください。
私もまだまだこの辺りは初心者ですが、今回の範囲を触っただけでもGitHub Actionsで多くのことができる可能性を感じました。別の作業でPythonのオートフォーマットをしたのですが、Rやhtmlはできていないのでそれは実現したいです。
ソースコード
on:
push:
branches:
- main
name: deploy-shiny
jobs:
build:
runs-on: Ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build image
run: docker build -t main .
- name: execute
run: >
docker run
-e SHINY_ACC_NAME='username'
-e TOKEN=${{secrets.SHINYAPPS_TOKEN}}
-e SECRET=${{secrets.SHINYAPPS_SECRET}}
-e MASTERNAME='appname'
main
# rockerの利用
FROM rocker/shiny
# 関連ライブラリのインストール
RUN install2.r rsconnect dplyr ggplot2
# デプロイファイルの準備
WORKDIR /home/shinyusr
COPY ui.R ui.R
COPY server.R server.R
RUN mkdir www
COPY www/favicon.ico www/favicon.ico
# デプロイの実行
COPY deploy.R deploy.R
CMD Rscript deploy.R
library(rsconnect)
setAccountInfo(name = Sys.getenv("SHINY_ACC_NAME"),
token = Sys.getenv("TOKEN"),
secret = Sys.getenv("SECRET"))
deployApp(appFiles = c("ui.R", "server.R", "www/favicon.ico"),
appName = Sys.getenv("MASTERNAME"))
Discussion