R Advent Calendar 2020の9日目の記事です。
書くのを決めた段階(7日目)でアドベントカレンダーにクラウド含む環境構築記事が複数公開されていたものの、ローカルでDockerを使う方法については書かれていなかったので一定の価値があるのではないかと考えて急遽書きました。
色々試行錯誤しこの形で安定してきているものの内容に自信がないので、誤り等については指摘していただければ助かります。
2020/12/13 12/10に公開されたDocker Desktop 3.0.0に関する情報を追記。
2021/09/19 Remote-Containers拡張で追加できるR定義をベースにしたものに更新。
概要
Windowsマシンで良い感じにLinuxを動かすWSL2が、この半年間で大多数のWindows10から使えるようになっています。
そこで私はRおよびRStudioをWindows10にもUbuntuにもインストールせず、Dockerコンテナ内にインストールされたRとRStudio Serverを使うようになりました。
↓のようにブラウザからアクセスします。
以下のようなソフトウェアをインストールし、Dockerイメージはrocker/tidyverseや日本語向けのrockerjp/tidyverseを使わせていただいています。
- Windows10
動機
rockerを使う動機
WindowsでR+RStudioを使っていてそれまでに幾度か、日本語版Windows版特有の(Shift-JIS由来の)以下のような問題に苦しめられました。
- 文字化け(ドキュメントフォルダがOneDrive上の「ドキュメント」だったせいで全角パスがRの環境変数に紛れ込んだ)
- 文字化け(コマンドライン、最近文字化けしなくなったらしいです→朗報! R 4.0.3からはcmdやPowerShellでRを起動しても文字化けしない)
- 文字化け(R Notebook、設定により直るらしいです→r-wakarang slackの投稿)
なのでWSLでRを使いたいとずっと思っていたのですが、WSL1では同じスクリプトを実行してもWindows側で実行するよりも目に見えて時間がかかってしまっていました。
今年の夏に自分のPCでもWSL2が使えるようになったので、Shift-JISから解放されると同時に環境のスクラップ&ビルドも容易になるということで、rockerに乗り換えることにしました。
VSCode DevContainerを使う動機
私はバージョン管理のためのGit操作はVSCodeのGUIから行っていたので(Git Graphオススメです)元々VSCodeとRStudioを併用していました。
rockerの使い方を試行錯誤している内にVSCodeの拡張機能であるRemote - Containersの面倒見の良さ(?)に感激し、今の状態に至っています。
コンテナ上のワークスペースをローカルと同じようにVSCodeが記憶する(最近使用した項目)のでコンテナの立ち上げ直しが楽だったり、コンテナ立ち上げ時に.gitconfig
を自動でコンテナ内にコピーしてくれるのでコンテナ内でも何も考えずにGitで変更をcommitできたりします。
ソフトウェアのインストール
以下、それぞれの詳細なインストール方法はネット上にたくさん情報があるので省きます。
WSL2の有効化とUbuntuのインストール
とりあえずUbuntuとしていますがもちろんUbuntu以外のディストリビューションで大丈夫です。
なおDockerホストのファイルをマウントする場合、Linux側のファイルシステム(Windowsからは\\wsl$\Ubuntu
でアクセス)を使わないと読み書き速度が低下するため、作業フォルダはLinux側に置いた方が良いです。Windowsからのアクセスがしづらくなるのは悩み所ですが。
Docker Desktopのインストール
注意点として、Windowsのバージョンが1903/1909の場合はEdge版を選ぶ必要がありました(2020年8月の情報、現在はどうなっているのか不明)。 →2020年12月10日に公開されたDocker Desktop 3.0.0でStable版とEdge版という二つのチャネルは廃止されたので、普通にインストールすれば大丈夫です。(窓の杜の記事)
Visual Studio Codeのインストール
VSCodeをインストールしたら、拡張機能のRemote - ContainersとDockerもインストールします。
Docker拡張機能はあるとコンテナの様子をVSCode上から確認できるようになって便利ですがなくても良いです。本記事内でも使用しません。
設定ファイルの準備
以下のような設定ファイルとフォルダをワークスペース(プロジェクト)として用意します。worksフォルダをワークスペースとして使用します。
Remote-Containers拡張機能のremote-containers.createDevContainerFile
コマンドによって追加できるR定義をベースに編集しています。
.
├── .devcontainer
│ ├── Dockerfile
│ ├── devcontainer.json
│ └── library-scripts
│ └── common-debian.sh
├── .env
├── docker-compose.yml
└── works
.devcontainer/devcontainer.json
VSCode Remote-Containersがコンテナを立ち上げるときに使うファイルです。今回はdocker-compose.yml
を参照してコンテナを立ち上げるように書かれています。Remote-Containers拡張機能で追加できる定義からdocker-composeを使用するように変更し、remoteUser
をrstudio
にしただけです。
{
"name": "${localWorkspaceFolderBasename}",
"dockerComposeFile": ["../docker-compose.yml"],
"service": "rstudio",
"workspaceFolder": "/home/rstudio/works",
"settings": {
"r.rterm.linux": "/usr/local/bin/radian",
"r.bracketedPaste": true,
"[r]": {
"editor.wordSeparators": "`~!@#%$^&*()-=+[{]}\\|;:'\",<>/?"
},
"terminal.integrated.profiles.linux": {
"radian": {
"path": "/usr/local/bin/radian",
"overrideName": true
}
}
},
"extensions": ["ikuyadeu.r"],
"shutdownAction": "none",
"remoteUser": "rstudio"
}
コンテナの設定やコンテナ内にインストールされるVSCodeの設定を記述できます。コンテナ内のVSCodeにインストールされる拡張機能も指定でき、上のものではR拡張をインストールするようになっています。汎用的に使う拡張機能はsettings.jsonのremote.containers.defaultExtensions
で指定すれば自分で作成したすべてのコンテナにインストールされるので便利です。
devcontainer.json
の書き方については公式ドキュメントに大量の解説があるので、設定に困ったらこれを読みましょう。
VSCodeの「フォルダーを開く」でこのファイルの含まれるフォルダをワークスペースとして開くと、下の画像のようにコンテナでワークスペースを開き直すか聞かれます。これで「Reopen in Container」を選択するとVSCodeがDockerを操作してコンテナを作り、vscode-serverをインストールし、拡張機能をインストールしワークスペースを開く……というところまで一気にやってくれます。
一度開いたワークスペースは「最近使用した項目を開く」から開けるので、二回目以降は直接コンテナ内のワークスペースを開くこともできます。
.env
コンテナ内に読み込まれる環境変数の内、個々人で別の値を設定したいものを書いておくためのファイルです。今回はdocker-compose.yml
から参照しています。
PASSWORD=pass
RStudioのログインパスワードを指定する環境変数${PASSWORD}
を定義しています。このようにパスワードを定義してやると、「Username:rstudio、Password:pass」でRStudio Serverにログインできます。
自分だけが見るので、このファイルはGitの管理対象外にします。
Dockerfile
Dockerイメージの作り方を記述するファイルです。Remote-Containers拡張機能で追加できる定義からベースイメージをrocker/tidyverse:latest
に変更しUSERNAME
をrstudio
に変更しただけです。
FROM rocker/tidyverse:latest
# Use the [Option] comment to specify true/false arguments that should appear in VS Code UX
#
# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="false"
# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
ARG USERNAME=rstudio
ARG USER_UID=1000
ARG USER_GID=$USER_UID
COPY library-scripts/*.sh /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true" \
&& usermod -a -G staff ${USERNAME} \
&& apt-get -y install \
python3-pip \
libgit2-dev \
libcurl4-openssl-dev \
libssl-dev \
libxml2-dev \
libxt-dev \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts \
&& python3 -m pip --no-cache-dir install radian \
&& install2.r --error --skipinstalled --ncpus -1 \
devtools \
languageserver \
httpgd \
&& rm -rf /tmp/downloaded_packages
# VSCode R Debugger dependency, install the latest release version from GitHub.
RUN Rscript -e 'remotes::install_github("ManuelHentschel/vscDebugger@*release", dependencies = FALSE)'
# R Session watcher settings.
# See more details: https://github.com/REditorSupport/vscode-R/wiki/R-Session-watcher
RUN echo 'source(file.path(Sys.getenv("HOME"), ".vscode-R", "init.R"))' >> ${R_HOME}/etc/Rprofile.site
せっかくVSCodeを使うので、devcontainer.json
でインストールするよう指定したR LSP Clientを動かすために、rocker/tidyverseに含まれていないlanguageserverパッケージをコンテナ内にインストールするようにしています。
コンテナ内で使うパッケージが増えたら、このファイルを編集してイメージビルドの段階でインストールされるようにします。
docker-compose.yml
コンテナを立ち上げるときに使われる設定ファイルです。Dockerfile
と.env
を参照しています。
version: '3'
services:
rstudio:
env_file: .env
build:
context: ./.devcontainer
environment:
- TZ=Asia/Tokyo
ports:
- "8787:8787"
volumes:
- ./.rstudio_config:/home/rstudio/.config
- ./works:/home/rstudio/works
./.rstudio_config:/home/rstudio/.config
の部分でRStudioの設定を永続化しています。
今回の用途なら.devcontainer/devcontainer.json
だけでも同等の設定を書くこともできますが、慣れているのでdocker-composeを使っています。
もちろんVSCodeを経由せずともdocker-compose up -d
とPowerShellでコマンド実行すればRStudioを使えます。
使い方
- VSCodeで設定ファイルの含まれた、ワークスペースとなるフォルダを開きます。
- 「Reopen in Container」を選択してコンテナを立ち上げます(右下の通知 or Shift+Ctrl+Pで出てくるコマンドパレット)
- コンテナ内でワークスペースが開かれるまで待ちます。ワークスペースが開かれるとVSCode左下の謎の緑のマークの隣に「Dev Container: (フォルダ名)」と表示され、その右隣に「使用可能なポートが1個あります」と表示されます。
-
localhost:8787
をブラウザで開きます。 - 「Username:rstudio、Password:pass」と、
.env
で指定したパスワードであるpassを入力してRStudioにログインします。 - 右上の「Project: (None)」→「Open Project」で「work」を開きます。
- これでVSCodeもRStudioもコンテナ内で使えるようになったので、Shift-JISのことは忘れて好きなように作業します。
- RStudioでの作業を終えたら、右上の電源ボタンを押してセッションを終わらせます。
- 作業の最後に、VSCodeで左下の謎の緑のマークを押して出てくるメニューの一番下の「リモート接続を終了する」を選択し、リモートワークスペースを閉じます。
おわりに
Linuxを使うことでShift-JISから解放されたと思いきや、「Excelでグラフ作るからcsvファイルくれ」と要求され直接Excelで開くのではなくcsvをインポートする方法を説明するのもめんどくさくてShift-JISなcsvファイルを作って渡したりしており、結局Shift-JISから逃れきれてはいません。
戦いは続く……。