Rパッケージは CRAN からインストールするのが普通ですが、 まだ CRAN に登録されていない開発版のRパッケージや、独自に開発したRパッケージを GitHub からインストールして使いたいこともあります。
この記事では Docker イメージ rocker/rstudio や rocker/tidyverse をベースに、GitHub上にあるRパッケージをインストールして新しいDockerイメージをビルドしたいという場面を考えます。
GitHub上のリポジトリからRパッケージをインストールするには、
remotes
パッケージの install_github
関数
を使用するのが便利です。その際、プライベートリポジトリに接続するため、あるいはGitHub APIの呼び出し頻度制限を緩和するため、Personal Access Token による認証が必要になります。
関数 install_github
を実行する際、あらかじめ環境変数 GITHUB_PAT
に Personal Access Token の値が入れてあれば自動的に認証が行われます。通常の利用時(Desktop版RStudioやRStudio Server上の操作でインストールする場合)はそれで良いのですが、Dockerイメージのビルド中に Personal Access Token を使用する場合は、ビルドされたイメージ内に Personal Access Token が残らないよう安全に取り扱う必要があります。
Dockerイメージのビルドにおける秘密情報の扱いについては 前の記事 にまとめました。
この記事では Personal Access Token の取り扱いについて
- Buildkit の
RUN --mount=type=secret
を利用する - マルチステージビルドを利用する
の2つの方法を適用する例を示します。
なおこの記事のサンプルコードは GitHub でも公開しています。
事前準備
インストールしたいRパッケージが GitHub のリポジトリ https://github.com/username/pkgname
にあるものとします。
username/pkgname
は適当なユーザー名やリポジトリ名に読み換えてください(例: tidyverse/tidyr
など)。
このリポジトリにアクセスできるGitHubユーザーアカウント(つまり自分のGitHubアカウント)で Personal Access Token を作成しておきます。
Buildkit の RUN --mount=type=secret
を利用する方法
この方法は秘密情報を受け渡すための専用機能を使うため、可読性が高く安全です。 その反面、BuildKit対応の環境でしか使えず、Docker Compose との併用ができないという難点もあります。
手順
作業ディレクトリに .env
ファイルと Dockerfile
を作成します。
.env
ファイルは次のような内容とします:
GITHUB_PAT=[Personal Access Token の値]
Dockerfile
の内容は以下のようにします:
# syntax = docker/dockerfile:1.0-experimental
FROM rocker/tidyverse:3.6.3
RUN \
set -a && . /run/secrets/.env && set +a \
&& install2.r remotes \
&& installGithub.r username/pkgname
この状態で次のコマンドを実行すると、Rパッケージ username/pkgname
をインストールした Docker イメージ myrstudio:latest
がビルドされます:
DOCKER_BUILDKIT=1 \
docker build -t myrstudio:latest \
--secret id=dotenv,src=.env \
.
解説
上のビルドコマンドでは秘密情報の書き込まれたファイル .env
をマウントするため
- 環境変数
DOCKER_BUILDKIT=1
の設定によって BuildKit を有効にする --secret id=dotenv,src=.env
のオプションによって.env
ファイルをIDdotenv
のシークレットとして渡す
という対応を行っています。
一方 Dockerfile
では次のようにして .env
ファイルを受け取り環境変数 GITHUB_PAT
を設定しています:
- 1行目のコメント
# syntax = docker/dockerfile:1.0-experimental
によってRUN --mount=type=secret
の文法を有効化 RUN --mount=type=secret,id=dotenv,dst=/run/secrets/.env ...
で.env
ファイルをコンテナ内のファイルパス/run/secrets/.env
にマウント- コマンド
set -a && . /run/secrets/.env && set +a
によって.env
ファイルの内容で環境変数を設定
そして、RUN
の残りのコマンド install2.r remotes && installGithub.r username/pkgname
で GitHubリポジトリ username/pkgname
からRパッケージをインストールしています。このとき remotes
パッケージの install_github
関数が呼び出され、環境変数 GITHUB_PAT
に設定された Personal Access Token が認証に使用されます。
RUN --mount=type=secret
でマウントされたファイルはビルドされたイメージに残らないことが保証されているため、Personal Access Token を安全に渡すことができています。
マルチステージビルドを使う方法
BuildKit
の RUN --mount=type=secret
と異なり、マルチステージビルドは本来秘密情報を扱うための仕組みではないので可読性の面で劣ります。中間イメージと最終イメージの違いを意識し、最終イメージに秘密情報が残らないよう注意して運用する必要があります。
個人的には Docker Compose を使いたい場合に限ってこの方法を採用することにしています。
手順
作業ディレクトリに Dockerfile
を以下の内容で作成します:
FROM rocker/rstudio:3.6.3 AS builder
ARG GITHUB_PAT
RUN install2.r remotes && installGithub.r username/pkgname
FROM rocker/rstudio:3.6.3
COPY /usr/local/lib/R/site-library /usr/local/lib/R/site-library
次のコマンドを実行すると、Rパッケージ username/pkgname
をインストールした Docker イメージ myrstudio:latest
がビルドされます:
docker build \
-t myrstudio:latest \
--no-cache \
--build-arg GITHUB_PAT=[Personal Access Token の値] \
.
解説
上のビルドコマンドでは、オプション
--build-arg GITHUB_PAT=[Personal Access Token の値]
で環境変数 GITHUB_PAT
に Personal Access Token のを渡しています。
前の記事 でも述べた通り、本来はこのように --build-arg
で秘密情報を渡すのは非推奨とされています(参考: Docker 公式ドキュメント)。
docker build
が実行されると、まず Dockerfile
の前半部分
FROM rocker/rstudio:3.6.3 AS builder
ARG GITHUB_PAT
RUN install2.r remotes && installGithub.r username/pkgname
で中間イメージ builder
のビルドが行われます。
このとき --build-arg
で渡された変数 GITHUB_PAT
を使用し、GitHubから username/pkgname
パッケージをインストールしています。
これで中間イメージ builder
のライブラリ /usr/local/lib/R/site-library
に username/pkgname
パッケージがインストールされた状態になります。
続けて Dockerfile
の後半部分
FROM rocker/rstudio:3.6.3
COPY /usr/local/lib/R/site-library /usr/local/lib/R/site-library
で中間イメージ builder
のライブラリ /usr/local/lib/R/site-library
が最終イメージにコピーされます。
これで最終イメージのライブラリに username/pkgname
パッケージがインストールされた状態になります。
中間イメージ builder
のレイヤーは最終イメージに保存されないので、--build-arg
で渡された Personal Access Token の値は最終イメージに残らないようになっています。
マルチステージビルド + Docker Compose
マルチステージビルドは Docker Compose と併用できるので、
docker build
コマンドのオプション --build-arg GITHUB_PAT=[Personal Access Token の値]
で与える変数 GITHUB_PAT
を設定ファイル docker-compose.yml
で管理することができます。
まず以下のような内容の .env
ファイルを作成し、Personal Access Token の値を保存します:
GITHUB_PAT=[Personal Access Token の値]
次に設定ファイル docker-compose.yml
を以下の内容で作成します:
version: "3.7"
services:
myrstudio:
image: myrstudio:latest
build:
context: .
args:
GITHUB_PAT: ${GITHUB_PAT}
ports:
- "8787:8787"
environment:
- PASSWORD=password
- DISABLE_AUTH=true
Dockerfile
の内容は上と変わりません。
この状態で次のコマンドを実行すると Docker イメージ myrstudio:latest
のビルドが行われます:
docker-compose build --no-cache
解説
Docker Compose では .env
ファイルの内容が反映されます(参考)。
設定ファイル docker-compose.yml
でビルドに関する記述はこの部分です:
build:
context: .
args:
GITHUB_PAT: ${GITHUB_PAT}
ここで .env
に書き込まれた GITHUB_PAT
の値がビルド変数 GITHUB_PAT
として渡されるよう設定しています。