cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

DockerイメージでGitHub上のRパッケージのインストールを行う際の注意: GitHub Personal Access Tokenの設定

前回の記事では、CRANやそれ以外のGitリポジトリからRパッケージのインストールを行うremotesパッケージの特徴と、GitHubで管理されたパッケージのインストールを行う際のAPIに関する注意を書きました。

uribo.hatenablog.com

今回はさらにニッチな内容だと思いますが、DockerでRStudio Serverを利用する際に、GitHub上のパッケージをインストールする必要がある時のtipsとなります。昨年末、仕事納め間際にハマってしまった障害とその解決策の備忘録でもあります。

要約

  • DockerコンテナでGitHubからインストールするRパッケージがある場合もGitHub Personal Access Token (PAT) の設定が必要
  • Dockerコンテナ上のRStudio Serverを立ち上げる際は/usr/local/lib/R/etc/RenvironにPATを保存する
  • PATをバージョン管理の対象、dockerイメージ間で共有しないようにするには.envargsコマンドを活用する

f:id:u_ribo:20190115063923p:plain

背景

普段の分析作業はDockerで起動するRStudio Server上で行なっています(過去のブログ記事を参考)。そのコンテナイメージはrockerプロジェクトをベースにしており、プロジェクトに応じて、追加で必要なパッケージをlittlerのコマンドを使って次のように記述し、インストールを行うようにしています1

FROM rocker/tidyverse:3.5.2

RUN set -x && \
  install2.r --error \
    jpmesh && \
  installGithub.r \
    uribo/fgdr

install2.rはCRAN上のパッケージ名、installGithub.rGitHubリポジトリを指定しています。

このうち、installGithub.rは、remotesパッケージの関数install_github()の機能をコマンドライン上で実行可能にしたものです

また、RStudio Server以外のコンテナイメージを併用することがあるためdocker-compose.ymlによる管理を行なっています。環境変数"PASSWORD"は、下記の記事で書いた通り、RStudio Serverへのログインに使われるパスワードです。パスワード自体は.envファイルに記述されており、他者と共有しないようにしています。

version: "3"
services:
  rstudio:
    build:
      context: "."
    ports:
      - "8787:8787"
    volumes:
      - ".:/home/rstudio/hatena_blog"
    environment: 
      PASSWORD: ${PASSWORD}

uribo.hatenablog.com

問題の発生

いつもこのようにして、パッケージの変更があるたびにDockerfileをビルドし直していたのですが、ある日パッケージの追加を行なって再度ビルドを行おうとした時、次のエラーメッセージを吐いてコンテナの起動に失敗してしまいました。

Error: HTTP error 403.
  API rate limit exceeded for XXX.XXX.XX.XXX. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)


  Rate limit remaining: 0/60
  Rate limit reset at: 2018-12-28 00:08:59 UTC


  To increase your GitHub API rate limit
  - Use `usethis::browse_github_pat()` to create a Personal Access Token.
  - Use `usethis::edit_r_environ()` and add the token as `GITHUB_PAT`.

これは、前回の記事でも取り上げたように、installGithub.rの実行時に認証を行わないAPI利用の上限に達してしまったことが原因です。問題解決のためには、GitHub Personal Access Tokenを環境変数に定義して、認証付きのAPI実行に切り替える必要があります。

対策

いくつかの方法があるかと思いますが、次の処置をとりました。大きくまとめると次の2ステップです。

  • docker-compose.ymlでのargsコマンドを利用した
    • GitHub PATは .env に記述
  • Dockerfileでの環境変数の定義

まずdocker-compose.ymlでargsコマンドによるGitHub PATの環境変数の指定とdockerfile中で環境変数の参照、Renvironファイルへの記述を行えるようにしておきます。具体的にはdocker-compose.ymlのbuild以下を次のように変更します。

  build:
    context: "."
    args:
      - GITHUB_PAT=<取得したGitHub PAT>

続いてdockerfileには次の行を追加します。

ARG GITHUB_PAT

RUN set -x && \
  echo "GITHUB_PAT=$GITHUB_PAT" >> /usr/local/lib/R/etc/Renviron

これにより、docker-compose.ymlで定義した環境変数がDockerイメージでも利用できるようになり、適切なGitHub PATを渡しておけば問題を回避することができます。しかし、これらのファイルはGitHubでも管理しているため、個人用のPATをベタ打ちするのは好ましくありません。そこでRStudio Serverへのログイン同様、.envでPATの記述を行うようにしました。

GITHUB_PAT=<取得したGitHub PAT>

docker-compose.ymlの方も.envの値を参照するように変更して完了です。最終的には次のようになります。

version: "3"
services:
  rstudio:
    build:
      context: "."
      args:
        - GITHUB_PAT=${GITHUB_PAT}
    ports:
      - "8787:8787"
    volumes:
      - ".:/home/rstudio/hatena_blog"
    environment: 
      PASSWORD: ${PASSWORD}
FROM rocker/tidyverse:3.5.2

ARG GITHUB_PAT

RUN set -x && \
  echo "GITHUB_PAT=$GITHUB_PAT" >> /usr/local/lib/R/etc/Renviron

RUN set -x && \
  install2.r --error \
    jpmesh && \
  installGithub.r \
    uribo/fgdr && \
  rm -rf /tmp/downloaded_packages/ /tmp/*.rds

これでプライベートリポジトリを含むGitHub上のパッケージをインストールしたイメージファイルが立ち上がります。

参考記事

docker-compose.ymlの中で環境変数を展開する - Qiita

docker-composeから環境変数をDockerfileに渡す方法 - Qiita


  1. rockerプロジェクトのコンテナイメージにはlittlerを使ったコマンドが用意されています。 https://github.com/rocker-org/rocker/blob/6bd244a33892af6e3ee797342b3f4ca9a6a559a0/r-base/Dockerfile#L51-L55