WSL2 + Docker + VS CodeでゼロからRの解析環境をつくる
1. はじめに
1.1. この記事の趣旨
この記事は、GNU R(以下、R)の解析環境を、Windows Subsystem for Linux (WSL) 2 + Docker + Visual Studio Code(VS Code)でセットアップする手順をまとめたものです。時間をかけずに再現・共有可能な統計解析環境を作りたいと思い、備忘録を兼ねて書きました。
1.2. 背景
私の専門は医療分野のメタアナリシスの応用で、解析にはRを使用しています。これまではWindows 10 + R + RStudio Desktopという環境で解析をしていたのですが、日本語版のWindows 10とRおよびRStudio Desktopの組み合わせには文字コードの相違に由来した不具合が複数あり、解決することが困難でした。
Windows 10にはWSLというWindows上でLinux環境を動かす仕組みがあり、バージョン2のアーキテクチャ(WSL2、May 2020 Updateで正式リリース)では従来あったLinuxとの互換性の問題が解決され、パフォーマンスも改善されました。そこで、Windows上でRを実行するのではなく、WSL2-Linux上でRを実行することで、文字化けして読めないエラーコードとおさらばすることにしました。
また、ここ最近は統計解析に関する論文を出版する際に、解析コードやデータセットを共有しようという潮流があり、私も自分の解析環境を簡単に共有・再現できたらいいなと思うようになりました。WSL2をバックエンドにするとDockerがすんなり動くようなので、RとRStudioはコンテナー上で動かすことにしました。WindowsとLinuxの両方で作業することになるので、WSL上のコンテナーはVS codeのリモート開発機能を利用して操作することにしました。
1.3. 実行環境
- OS:Windows 10 Pro(バージョン:21H2、OSビルド19044.1586)
1.4. やりたいこと
Dockerと、Rの checkpoint
パッケージで解析環境全体のバージョンを管理し、他のユーザー(研究者)が同じ環境を簡単に再現できるようにする。
- VS Codeをインターフェイスとして、WSL2-Linux上でDockerを使用する。
- Docker Compose V2でrocker/rstudioイメージからR + RStudio環境を立ち上げる。
- WSL2-LinuxのGitでソースコード等をバージョン管理し、最終的にGitHub + 論文で公開する。
2. 解析環境の構築
2.1. 手順
以下の順番で進めます。
- WSL2を有効化し、Ubuntuをインストールして設定する
- Docker Desktop for Windowsをインストールして設定する
- VS Codeをインストールして設定する
- Gitをインストールして設定する
- Rプロジェクトを作成する
- VS codeからRStudio Serverを起動する
2.2. WSL2を有効化し、Ubuntuをインストールして設定する
2.2.1. 参照したドキュメント
2.2.2. WSL2の有効化
管理者権限のPowerShellで以下のコマンドを入力して実行し、PCを再起動します。
wsl --install
2.2.3. Ubuntuのインストールと設定
PCを再起動すると、Ubuntuのターミナルが開いてインストールが進行します。Ubuntuのインストール完了後に、Linuxのユーザー名とパスワードを設定します。そのまま、ターミナルでログインシェル:bashが起動していますので以下のコマンドを実行し、Ubuntuのパッケージ管理システム:Advanced Packaging Tool(APT)のライブラリを更新してからパッケージをアップグレードします。
sudo apt update && sudo apt upgrade
Windows-Linux間でファイルのやり取りをしようとすると、ファイルシステムが異なるため処理に時間がかかります。そのため、原則として統計解析に使用するファイルはすべてLinuxファイルシステム内に配置します。Windowsファイルシステムから統計解析で使用するファイルにアクセスしたい場合は、以下のコマンドを実行し、カレントディレクトリをエクスプローラーで開きます。この時、Windows側から仮想的なホスト wsl$
を介したファイル共有という形で、Linuxファイルシステムにアクセスしています。
explorer.exe .
LinuxディストリビューションとWSLのバージョンを確認しておきます。PowerShellで以下のコマンドを実行します。
wsl --list --verbose
【実行結果】
NAME STATE VERSION
* Ubuntu Running 2
Ubuntuがインストールされており、WSL2で稼働中であることが確認できます。これだけではUbuntuのバージョンがわかりませんが、この「無印Ubuntuアプリケーション」では、インストール時点で最新の長期サポート(LTS:Long Term Support)版が提供される仕様です。
bashで以下のコマンドを実行することでインストールされたUbuntuのバージョンを確認できます。
lsb_release --all
【実行結果】
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal
2022年3月時点で最新のUbuntu 20.04.4 LTSがインストールされていることがわかります。なお、すでにインストールされているUbuntuは自動でアップグレードされるわけではないため、必要に応じて以下のコマンドを実行し、自分でアップグレードする必要があります。Ubuntu 20.04 LTSのサポートは2025年4月までです。
sudo do-release-upgrade
2.2.4. Windows Terminalの設定(オプション)
Windows Terminalを使用している場合は、以下のように設定します。
- Ubuntuの開始ディレクトリを
\\wsl$\Ubuntu\home\UseName
に変更する
2.3. Docker Desktop for Windowsをインストールして設定する
2.3.1. 参照したドキュメント
2.3.2. Docker Desktop for Windowsのインストール
インストーラーを使ってDocker Desktop for Windowsをインストールします。今回はDocker Desktop 4.6.0をインストールしました。インストールが完了したら、スタートメニューからDocker Desktopを起動し、設定画面に移動し、以下のように設定を変更・確認します。
- Setting > General
- "Open Docker Dashboard at startup" のチェックを外します
- "Use the WSL 2 based engine" がオンになっていることを確認します
- Setting > Resources > WSL Integration
- "Enable integration with my default WSL distro" がオンになっていることを確認します
- "Enable integration with additional distros" で必要な他のディストリビューションでもWSL統合を有効にします(今回は該当なし)
以下のコマンドを実行し、DockerとDocker Composeのバージョンを表示することで、インストールされていることを確認します。
docker --version && docker-compose --version
【実行結果】
Docker version 20.10.13, build a224086
Docker Compose version v2.3.3
2.3.3. Hello world
単純なDockerイメージを呼び出して、機能をテストします。
docker run hello-world
【実行結果(抜粋)】
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:4c5f3db4f8a54eb1e017c385f683a2de6e06f75be442dc32698c9bbe6c861edd
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
Hello ! 問題なさそうですね。
2.4. VS Codeをインストールして設定する
2.4.1. 参照したドキュメント
2.4.2. VS Codeのインストール
インストーラーを使用し、VS CodeをWindowsにインストールします。
2.4.3. 拡張機能
VS Codeに基本的な拡張機能をインストールします。
- Material Icon Theme
- Remote Development
- Character Count
- Docker
- Git Graph
- Markdown All in One
- markdownlint
- Rainbow CSV
- テキスト校正くん
2.4.4. エディターの設定
ファイル > ユーザー設定 > 設定と移動し、エディターの設定を変更します。私の場合は以下のように変更しました。
- ウインドウのタイトルにファイルの絶対パスを表示する
-
Window: Title
を${dirty}\${activeEditorLong}${separator}${rootName}
に変更する
-
- 空白文字を常に表示する
-
Editor: Render Whitespace
をall
に変更する
-
- ミニマップの表示領域を常に表示する
-
Editor > Minimap: Show Slider
をalways
に変更する
-
- ツリーのインデントを深く設定する
-
Workbench › Tree: Indent
を16
に変更する
-
- インデントガイドを常に表示する
-
Workbench › Tree: Render Indent Guides
をalways
に変更する
-
- 角かっこのペアの彩色とブラケットペアのガイドを有効にする
-
Editor › Bracket Pair Colorization: Enabled
をチェックする -
Editor › Guides: Bracket Pairs
をtrue
に変更する
-
- 目次に含める見出しレベルを変更する
-
Markdown › Extension › Toc: Levels
を1..2
に変更する
-
2.4.5. WSL2-Ubuntuへの接続
WindowsからVS Codeを介してWSL2-Ubuntuに接続できるように設定します。さて、Microsoft docsには以下のような記載があります。
一部の WSL Linux ディストリビューションには、VS Code サーバーの起動に必要とされるライブラリが不足しています。(中略)wget (Web サーバーからコンテンツを取得するため) と ca-certificates (SSL ベースのアプリケーションで SSL 接続の信頼性を確認するのを許可するため) を追加するには……(後略)
そこで、以下のコマンドを実行し、Ubuntu 20.04 LTSに wget
と ca-certificates
がインストール済みかどうか、確認します。
apt list --installed | grep -E 'wget|ca-certificates'
【実行結果】
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
ca-certificates/focal-updates,focal-security,now 20210119~20.04.2 all [installed,automatic]
wget/focal-updates,now 1.20.3-1ubuntu2 amd64 [installed,automatic]
Ubuntu 20.04.4 LTSには wget
と ca-certificates
がインストール済みであることが確認できました。
以下のコマンドを実行し、WSL2-UbuntuからVS Codeを起動します。
code .
【実行結果】
Installing VS Code Server for x64 (c722ca6c7eed3d7987c0d5c3df5c45f6b15e77d1)
Downloading: 100%
Unpacking: 100%
Unpacked 1619 files and folders to /home/UserName/.vscode-server/bin/c722ca6c7eed3d7987c0d5c3df5c45f6b15e77d1.
初回の接続では、VS Code ServerがWSL2-Ubuntuにインストールされます。Windows側のVS Codeはインターフェースの役割をし、WSL2-Ubuntu上のVS Code Serverが仕事をする、といったところでしょうか。
2.4.6. WSL2のDNS設定変更
WSL2の既知の問題で、IPネットワーク上でドメイン名とIPアドレスの対応関係を解決するドメインネームシステム(DNS)の設定ファイル /etc/resolv.conf/
がおかしくなり、ネットワークに接続できなくなることがあります。根本的な原因は不明のようですが、設定ファイルの自動生成を停止してDNSを設定することで、問題を回避できます。
まず、WSL2をシャットダウンします。
wsl --shutdown
WSL2の起動時に、DNSの設定ファイル /etc/resolv.conf/
が自動で生成されて上書きされてしまうので、生成を停止します。/etc/wsl.conf
を作成して以下の内容を追記します。
sudo nano /etc/wsl.conf
【追記内容】
[network]
generateResolvConf = false
次に、既存の/etc/resolv.conf
を削除して、シンボリックリンクを一度削除します。
sudo rm /etc/resolv.conf
/etc/resolv.conf
を作成してDNSを設定します。今回はGoogle Public DNSにしました。もちろん、ホストであるWindowsでコマンドプロンプトから ipconfig
でDNSサーバ名を確認し、/etc/resolv.conf
に記載することでも問題ありません。
sudo nano /etc/resolv.conf
【追記内容】
nameserver 8.8.8.8
nameserver 8.8.4.4
とくにWSL2の再起動をしなくても、DNS設定が反映されます。
2.5. Gitをインストールして設定する
2.5.1. 参照したドキュメント
2.5.2. Windows側の設定
はじめに、GitHubのアカウントを作成しておきます。次に、WindowsにGit for Windowsをインストールします。基本的にはデフォルトの設定のまま進めますが、以下の項目は変更します。
- "Choosing the default editor used by Git" ではVS codeを選択する
- "Enable Git Credential Manager" にチェックを入れて有効化する
- "Enable symbolic links" にチェックを入れて有効化する
インストールが完了したら、Windows TerminalでもGit Bashを使えるように、新たなプロファイルを追加し、以下のように設定します。
- 名前 Git Bash
- コマンドライン
C:\Program Files\Git\bin\bash.exe
- 開始ディレクトリ
%USERPROFILE%
- アイコン
C:\Program Files\Git\mingw64\share\git\git-for-windows.ico
Git Bashで以下のコマンドを実行し、Gitのユーザー名とメールアドレスを設定します。GitHubで使用しているものと同じ設定にしました。
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"
2.5.3. WSL2-Ubuntu側の設定
WSL2-Ubuntuのbashでも同様にGitのユーザー名とメールアドレスを設定します。
git config --global user.name "Your Name"
git config --global user.email "youremail@domain.com"
WSL2-UbuntuでWindowsのGit Credential Manager(GCM)を使用するよう設定します。この設定をすることで、毎回認証要求をされずに済みます。
git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-credential-manager-core.exe"
2.6. makeをインストールする
2.6.1. 参照したドキュメント
- GNU Make (GNU Operating System)
- make (ubuntu manuals)
- bash (ubuntu manuals)
- Self-Documented Makefile (marmelab.com)
2.6.2. makeとは
makeは、プログラムのビルド作業を自動化するツールのひとつで、make
コマンドに実行させる手順を記述したテキストファイルをMakefileといいます。makeはファイルの依存関係を考慮しつつコンパイルを自動化するために開発されたツールですが、材料から何かを作るためのルールを記述する、一般的なツールとしても使用できます。今回はdockerの起動コマンドを短縮する目的で使用します。
2.6.3. makeのインストール
Ubuntu 20.04.4 TLSにはデフォルトで make
がインストールされていないので、以下のコマンドでインストールします。
sudo apt update && sudo apt upgrade
sudo apt install make
makeのバージョンを表示し、正しくインストールされたことを確認します。
make --version
【実行結果】
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
3. Rプロジェクトを作成する
3.1. 参照したドキュメント
- R Docker tutorial (jsta)
- The Rocker Images: choosing a container (The Rocker project)
- renv と Docker の相互運用パターン (terashim.com)
3.2. Rプロジェクトのひな型
DockerとRの renv
パッケージを使用したRプロジェクトのひな型を、MITライセンスで公開された方がいますので、こちらを参考としてRプロジェクトを作成します。私の場合は、論文の執筆に向いた特徴を備えている checkpoint
をパッケージ管理に使用しているため、Rプロジェクトの構成を大きく変更しました。詳細は以下の記事にまとめました。
3.3. リポジトリの作成とクローン
私は ~/res
ディレクトリを作成し、その下に各研究のRプロジェクトを配置することにしました。
cd
mkdir res
この記事では、テスト用に 2203_test
というプロジェクトを作成します。まずはひな型の説明に従い、GitHubでUserName/2203_test
リポジトリを作成後、 WSL2-Ubuntuの ~/res
ディレクトリにクローンします。クローンする際、初回ログインの場合はGCMの認証が求められます。
cd res
git clone https://github.com/UserName/2203_test.git
【実行結果】
Cloning into '2203_test'...
info: please complete authentication in your browser...
remote: Enumerating objects: 33, done.
remote: Counting objects: 100% (33/33), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 33 (delta 0), reused 23 (delta 0), pack-reused 0
Unpacking objects: 100% (33/33), 14.51 KiB | 874.00 KiB/s, done.
~/res/2203_test
ディレクトリが作成されました。これがそのままひとつのRプロジェクトです。ディレクトリの構造を確認するために、tree
パッケージをインストールします。
sudo apt update && sudo apt upgrade
sudo apt install tree
以下のコマンドを実行し、~/res
ディレクトリから4階層の構造を表示します。
tree -a -F -L 4 ~/res
【実行結果(一部編集しています)】
~/res
└── 2203_test/
├── .Rprofile.
├── .Rprofile 【R:セッション開始時に実行するスクリプト】
├── .checkpoint/ 【R:checkpointによるパッケージキャッシュ】
├── .env.example 【Docker Compose:環境変数の設定テンプレート】
├── .git/
├── .gitignore
├── LICENSE
├── Makefile 【Make:起動コマンド短縮】
├── README.md
├── codes/
│ ├── .gitignore
│ ├── README.md
│ ├── analysis.qmd 【Quarto:解析コードと結果の解釈】
│ ├── analysis_cache/
│ ├── analysis_files/
│ ├── datasets/ 【Quarto:データセット】
│ ├── figures/ 【Quarto:プロットの画像データ(.svg)】
│ └── templates/ 【Quarto:引用文献の書誌要素とスタイル定義】
├── compose.yml 【Docker Compose:設定ファイル】
├── dev/
│ ├── docker/
│ │ ├── .Renviron
│ │ ├── .ssh/
│ │ ├── Dockerfile 【Docker:設定ファイル】
│ │ └── startup.sh*
│ └── dotfiles/ 【RStudio:設定ファイル】
└── research.Rproj 【R:Rプロジェクトファイル】
4. VS codeからRStudio Serverを実行する
4.1. 参照したドキュメント
4.2. 起動と終了
Rプロジェクトを配置したディレクトリ(Makefileのある場所…今回は ~/res/2203_test
)で make up
コマンドを実行すると、バックグラウンドでRStudio Serverを起動します。ブラウザからRStudio Server (http://localhost:8787/) にアクセスすれば、解析が開始できます。同様に、make down
で終了、make
でコマンドのヘルプを閲覧できます。
【起動】
make up
【実行結果(抜粋)】
[+] Building 0.3s (12/12) FINISHED
[+] Running 1/0
⠿ Container r-project-rstudio-1 Running 0.0s
💡 Access: http://localhost:8787/
【終了】
make down
【実行結果】
[+] Running 2/2
⠿ Container r-project-rstudio-1 Removed 11.8s
⠿ Network r-project_default Removed 0.7s
【ヘルプを開く】
make
【実行結果】
Command list:
[Target] [Description] [Product]
help show a command list N/A
up build and run RStudio Server in the background docker compose up -d --build
down stop and remove running containers and networks docker compose down
stop stop running containers without deleting it docker compose stop
start (re-)start stopped containers docker compose start
ps list containers for the compose-project docker compose ps
prune delete unused Docker objects docker system prune -f
bash start bash in the rstudio container docker compose exec rstudio /bin/bash
4.3. 解析結果の再現手順
以下の手順で解析結果を再現できます。
- 最新のDocker EngineとDocker Composeが使用可能か確認し、必要に応じてインストールする
-
git
コマンドとmake
コマンドが使用可能か確認し、必要に応じてインストールする - 適当なディレクトリに、
git clone
コマンドでRプロジェクトをコピーする -
.env.example
をコピーし、.env
を作成する(オプション) - Docker daemonが起動している状態で、Rプロジェクトのディレクトリで
make up
コマンドを実行し、RStudio Serverを起動する - Rプロジェクトを開いてから、
codes
ディレクトリ内のanalysis.qmd
で解析を実行する - 解析が終わったら
make down
コマンドを実行し、終了!
以下の内容は統計解析には必須ではありません。Zennの設定です。
5. Zenn関連の設定(オプション)
5.1. ZennとGitHubを連携し、Zenn CLIをインストールする
5.1.1. 参照したドキュメント
- GitHubリポジトリでZennのコンテンツを管理する (Zenn)
- Node.js を Linux 用 Windows サブシステム (WSL2) にインストールする (Microsoft Docs)
- nvm-sh/nvm (GitHub)
- Zenn CLIをインストールする (Zenn)
5.1.2. リポジトリの作成とクローン
GitHubに新規のリポジトリ UserName/zenn
を作成します。コンテンツは空で、README.mdも不要です。bashで以下のコマンドを実行し、WSL2-Ubuntuのホームディレクトリにクローンします。
cd
git clone https://github.com/UserName/zenn.git
~/zenn
ディレクトリが作成されました。
5.1.3. Node.jsとZenn CLIのインストール
Zennのコマンドラインインターフェイス(Zenn CLI)は、サーバー側で動くJavaScript実行環境の1つ:Node.jsを使用しているため、まずはNode.jsをWSL2-Ubuntuにインストールします。以下のコマンドを実行し、Node Version Manager(通称nvm)をインストールします。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
続いて、以下のコマンドを実行し、nvmを読み込みます。
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
以下のコマンドを実行し、nvmが正しくインストールされたことを確認します。インストールに問題が無ければ nvm
と表示されます。
command -v nvm
【実行結果】
nvm
Node.jsのインストールにはC言語のコンパイラが必要になりますが、初期状態のUbuntu 20.04.4 LTSにはCコンパイラが含まれていないので、gcc
をインストールします。
sudo apt install gcc
安定バージョンのNode.jsをインストールします。最新のバージョンを共存させることもできますが、今回は省略します。同時にNode Package Manager(通称npm)もインストールされます。
nvm install --lts
Node.jsとnpmのバージョンを表示し、インストールされたことを確認します。
node --version
npm --version
~/zenn
ディレクトリに移動し、npmでプロジェクトを初期化し管理下に置きます。
cd zenn
npm init --yes
~/zenn
ディレクトリにZenn CLIをインストールします。
npm install zenn-cli
続いて、npxコマンドでローカルにインストールしたZenn CLIのバイナリを実行し、必要なディレクトリとファイルを作成すれば、導入完了です。
npx zenn init
5.1.4. 記事の作成
~/zenn
ディレクトリで以下のコマンドを実行すると、~/zenn/articles
ディレクトリに what-is-slug.md
が作成されます。
npx zenn new:article --slug what-is-slug
slug(スラッグ)はZennのコンテンツのユニークなIDで、https://zenn.dev/ユーザー名/articles/what-is-slug
というように、記事のURLにも含まれます。
~/zenn
ディレクトリで以下のコマンドを実行し、http://localhost:8000にブラウザで接続すると記事のプレビューを閲覧できます。
npx zenn preview
【実行結果】
👀 Preview: http://localhost:8000
以上で、WSL2 + Docker + VS CodeでRの解析環境が整いました。
Discussion