🕌

GitHub Actionsを使ってshinyapp.ioへ自動デプロイ

2023/06/13に公開

背景

これまでは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を押して全て表示させます。ここでtokensecretの値が大事なので、控えてください(画像では消しています)。

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.RCOPYする必要があります。

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はできていないのでそれは実現したいです。

ソースコード

auto_deploy.yml
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
Dockerfile
# 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
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