環境
OS: Windows 10 Pro バージョン 2004 (19041.572)
Visual Studio Code: 1.50.1
Docker Desktop: 2.5.0.0 (49427) stable
Docker: version 19.03.13, build 4484c46d9d
自分: DockerやWSLのことよくわかってないけどなんとなく使っている
WSL関連
$ wsl -l -v --all
NAME STATE VERSION
* docker-desktop-data Running 2
docker-desktop Running 2
Ubuntu Running 2
# WSL2上のUbuntu
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
[wsl2]
memory=2GB # ←ホストマシンのメモリがしょぼいので……
swap=0
使用したコード
project
└ .devcontainer
├ devcontainer.json
└ docker-compose.yml
各ファイルの中身
{
"name": "wsl-devcontainer-example",
"dockerComposeFile": "docker-compose.yml",
"service": "web",
"workspaceFolder": "/workspace"
}
version: '3'
services:
web:
image: node:14-alpine
tty: true
volumes:
- ..:/workspace
問題
開発コンテナを開いたら、以下のような警告が出た。
Docker Desktop - Filesharing
Docker Desktop has detected that you shared a Windows file into a WSL 2 container, which may perform poorly. Click here for more details.
(補足)そもそもdevcontainerって何
- VSCodeのメチャ便利機能
- 開発環境をDockerコンテナで作るのでホスト環境を汚さずにすむ
- 設定ファイルの用意さえすればVSCodeで開いてちょっとボタン押すだけで↑の環境ができてすごい楽
- 設定ファイルとDocker関連ファイルをリポジトリに入れておけば開発メンバーで環境を統一できてすごい
- Developing inside a Container using Visual Studio Code Remote Development
なんの警告?
上記リンク先から一部引用:
To get the best out of the file system performance when bind-mounting files, we recommend storing source code and other data that is bind-mounted into Linux containers (i.e., with
docker run -v <host-path>:<container-path>
) in the Linux file system, rather than the Windows file system. You can also refer to the recommendation from Microsoft.
ファイルをバインドマウントするときファイルシステムのパフォーマンスを最大限に活用するためには、ソースコードやその他、Linuxコンテナに(例えば
docker run -v <host-path>:<container-path>
を使って)バインドマウントされるデータを、WindowsファイルシステムではなくLinuxファイルシステムに保存することが推奨されます。マイクロソフトからの推奨事項も参考にしてください。
WSL2ではWindowsファイルシステム上に保存したファイルにWSL上のコマンドからアクセスするのはかなり遅いし一部機能が動かない、という警告のようだ。
確かに、npm install
のようなファイルを大量に書き込む処理をすると、めちゃめちゃ遅いのが体感できる。
解決方法
Windowsファイルシステムではなく、WSL上で作ったLinuxファイルシステムのディレクトリをdevcontainer
(開発用コンテナ)にバインドマウントしてやればよいはずである。
ダメな方法(1)
ただdocker-compose.yml
を以下のようにしてももちろんダメ。
version: '3'
services:
web:
image: node:14-alpine
tty: true
volumes:
- \\wsl$\Ubuntu\home\username\workspace:/workspace # ✖✖✖
docker-compose
が\\wsl$\...
をパスとして認識できないようで、動かない。さらに、これだと相対パスが使えないので、プロジェクトメンバーで共有もできない。そもそも「Windowsがネットワークドライブとしてマウントしたフォルダ」を指定しても、意味がない気がする。なにもかもがダメ
ダメな方法(2)
以下もダメ。
version: '3'
services:
web:
image: node:14-alpine
tty: true
volumes:
- /mnt/c/Users/username/workspace:/workspace # ✖✖✖
これもやはり相対パスが使えない。そして「WSLがマウントしたWindowsファイルシステム上のフォルダ」を指定しているので、意味がない気がする。(動くのかな?試してません……)
正しい方法
以下のドキュメントに、ステップバイステップのチュートリアルがある。
(1) WSLとdockerの環境を確認
前述のチュートリアルにもある通り、以下の環境が必要。
- Windows 10 バージョン2004 ビルド 18362以降 (エディションはHomeでOK)
- VSCodeにRemote Development 拡張セットを入れておく
- WSL2となんらかのディストリビューション(私はUbuntuにした)
- Docker Desktopの設定で
Use the WSL 2 based engine
を有効化 - Docker Desktopの設定で
WSL Integration
を有効化 - (ついでに)WSL2が無限にメモリ使いまくる問題に対処しておいた方がいいかも? 参考:WSL2によるホストのメモリ枯渇を防ぐための暫定対処 - Qiita
設定ができていると、WSL上のUbuntu上にdockerをインストールしなくても、docker
やdocker-compose
コマンドが使えるようになる。これが重要っぽい?(WSLからコンテナを起動するので)
$ docker --version
Docker version 19.03.13, build 4484c46d9d
$ which docker
/usr/bin/docker
$ ls -al /usr/bin/docker
lrwxrwxrwx 1 root root 48 Nov 5 10:47 /usr/bin/docker -> /mnt/wsl/docker-desktop/cli-tools/usr/bin/docker
(2) WSLからVSCodeを開く
WSLのUbuntuのシェルから操作する。
$ cd ~
$ git clone https://github.com/mattwojo/helloworld-django.git
$ cd helloworld-django
$ code .
VSCodeが開くと、プロジェクト内の.devcontainer
フォルダを認識して「Dev Container設定があるけど、コンテナで開く?」というようなメッセージを出してくるのだが、これは無視する。
どうも、このメッセージのボタンからコンテナを開くと、せっかくWSLからVSCodeを起動していても無視されて、Windowsから開発用コンテナを実行しようとしてしまうみたい……?
(3) VSCode(WSL)からコンテナを開く
- コマンドパレットから
Remote-Containers: Open Folder in Container...
を選択 - プロジェクトフォルダを選択(最初から選択されてたのでそのままOK)
この後、ドキュメントには
プロジェクトフォルダー (リポジトリ) に DevContainer 構成がまだないため、コンテナー定義の一覧が表示されます。
とあったが、現行バージョンだとリポジトリ内に.devcontainer
がすでに存在しているため、何も聞かれずイメージのビルドが始まる。(けっこう時間がかかった……)
VSCode上で統合ターミナルを開き、Pythonのバージョンを確認してみる。
$ python --version
Python 3.9.0
WSL(Ubuntu)にはpythonを入れていないので、コンテナのターミナルであることがわかる。
冒頭に示したFilesharingの警告も出ない!
(ちなみに、サンプルプログラムを実行するにはpython3 -m pip install django
が必要だった。)
元のファイルで試す
- 問題が出ていた
.devcontainer
を含んだプロジェクトフォルダを、\\wsl$\Ubuntu\home\username
以下に移動(Windowsのエクスプローラーで開いてコピーしただけ) - WSLのUbuntuのシェルから
code .
Remote-Containers: Open Folder in Container...
- できた!
次回からは?
毎回これをやるのは面倒だな……と思ったが、一度開けば次からはVSCodeの「最近」のところに[Dev Container]
と表示され、一発で開けるようになっていた。
まとめ
- コードをWSLのLinuxファイルシステム上に配置する
- VSCodeをWSLから
code
コマンドで開く ←これが重要 - WSLで開いたVSCodeから
Remote-Containers: Open Folder in Container...