概要
バージョン2004
で正式導入されたWSL2ですが、先日バージョン1909
と1903
へのバックポートが発表されました!
https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/
筆者の開発PCは2004
へのアップデートが許可されていないので、非常に助かります。
そこで今回は、Docker Desktop for Windows
のWSL2インテグレーション機能と、VSCodeのRemote - Containers
拡張機能を使って、Dockerfile
でコンテナ内にGo
の「快適な」開発環境を作ってみるところまでやってみようと思います。
※既に以下のような素晴らしい記事があり書くのを迷いましたが、自身の理解を深めるのと備忘録も兼ねて書きました。
https://tech-lab.sios.jp/archives/21675
筆者の環境
エディション | バージョン | OSビルド |
---|---|---|
Windows 10 Pro | 1909 | 18363.1049 |
システム要件
エディション | バージョン | OSビルド |
---|---|---|
Windows 10(全エディション) | 2004 | - |
Windows 10 x64(全エディション) | 1909 | 18363.1049 以上 |
Windows 10 x64(全エディション) | 1903 | 18362.1049 以上 |
手順
-
WSLをインストールし、WSL2に更新する
-
Docker Desktop for Windows をインストールする
-
VSCoceの拡張機能 Remote Containers を使って、Goの開発環境を構築する
1. WSLをインストールし、WSL2に更新する
以下URLの公式手順通りにやれば問題ありませんが、一応この記事でも手順を書いておきます。
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
1‐1. CPU仮想化が有効になっているか確認
タスクマネージャを開き、CPUの仮想化が有効となっていることを確認してください。
もし有効になっていない場合は、BIOS(UEFI)で仮想化を有効にしてください。(メーカーによって設定方法が異なるので説明は割愛します)
1‐2. Windows Subsystem for Linuxをインストールする
GUI(マウス操作)でやる場合
コントロールパネル
> プログラムと機能
> Windowsの機能の有効化または無効化
の順に選択して以下画面を開き、Linux用Windowsサブシステム
にチェックを入れます。
CUI(コマンド操作)でやる場合
管理者権限でPowerShellを開き、以下コマンドを実行してください。
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
成功すると以下のようなメッセージが表示されます。
展開イメージのサービスと管理ツール
バージョン: 10.0.18362.900
イメージのバージョン: 10.0.18363.1049
機能を有効にしています
[==========================100.0%==========================]
操作は正常に完了しました。
1‐3. 仮想化マシンプラットフォームのオプションコンポーネントを有効にする
GUI(マウス操作)でやる場合
先程と同様に、コントロールパネル
> プログラムと機能
> Windowsの機能の有効化または無効化
の順に選択して以下画面を開き、仮想マシンプラットフォーム
にチェックを入れます。
CUI(コマンド操作)でやる場合
管理者権限でPowerShellを開き、以下コマンドを実行してください。
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
成功すると以下のようなメッセージが表示されます。
展開イメージのサービスと管理ツール
バージョン: 10.0.18362.900
イメージのバージョン: 10.0.18363.1049
機能を有効にしています
[==========================100.0%==========================]
操作は正常に完了しました。
1‐4. PCを再起動する
PCを再起動してWSLのインストールとWSL2の更新を完了させます。
1‐5. WSL2を既定のバージョンとして設定する
新しいLinuxディストリビューションをインストールする際の既定のバージョンをWSL2に変更します。
PowerShellを開き、以下コマンドを実行してください。
wsl --set-default-version 2
以下のメッセージが表示された場合はLinuxカーネルを更新する必要があります。
WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
メッセージに表示されている以下URLにアクセスし、Linuxカーネル更新プログラムパッケージをダウンロードします。
https://aka.ms/wsl2kernel
ダウンロードしたインストーラーを起動し、Nextをクリックすればインストール完了です。
インストールが完了したら、再び以下コマンドを実行してみてください。今度は成功するはずです。
wsl --set-default-version 2
1‐6. Linuxディストリビューションのインストール
Microsoft Store
を開き、Linuxディストリビューションをインストールします。
wsl
で検索すればいくつか候補が出てきます。
インストールが完了したら、Ubuntu
を起動します。
しばらく待つとユーザー名とパスワードの入力を促されるので、任意のものを入力します。
※今後Ubuntu
内で何かするときはパスワード入力を求められるので、パスワードは忘れないでください。
これで、Windows上でLinux(Ubuntu)を起動できるようになりました!
念のためPowerShellを開き、以下コマンドを実行してWSLのバージョンが2になっていることを確認しましょう。
wsl -l -v
NAME STATE VERSION
* Ubuntu Running 2
2. Docker Desktop for Windows をインストールする
次に、Docker Desktop for Windows
をインストールし、Docker
を使えるようにします。
ここで注意点ですが、以下のリリースノートに記載してある通り、バージョンが1909
1903
の場合はDocker Desktop Community 2.3.5.0
以上をインストールする必要があります。
https://docs.docker.com/docker-for-windows/edge-release-notes/
執筆時点(2020年9月4日)では、Stable版(安定板)の最新バージョンはDocker Desktop Community 2.3.0.4
です。
筆者の環境はバージョン1909
なので、今回はEdge版をインストールします。
バージョン2004
の方はStable版でも問題ないと思います。
以下URLにアクセスし、Docker Desktop for Windows
のEdge版のインストーラーをダウンロードします。
https://hub.docker.com/editions/community/docker-ce-desktop-windows/
インストーラーを起動すると、最初にConfiguration画面が立ち上がります。
今回はDocker
のバックエンドをWSL2
にしたいので、Install required Windows components for WSL2
にチェックが入っていることを確認します。
従来のHyper-V型は使わないので、Enabled Hyper-V Windows Features
はオフにしておきます。
OKボタンをクリックするとインストールが始まります。以下画面が表示されたら成功です。
Close and log out
ボタンをクリックするとログアウトされるので、再度Windowsにログインします。
ログイン後、Docker Desktop for Windows
が自動的に起動します。
しばらく待って起動に成功すると以下画面が表示されます。
Start
ボタンをクリックするとチュートリアルが始まりますが、今回はSKIPします。
画面上部の歯車アイコンをクリックして、Generalの設定でUse the WSL2 backend engine
がチェックされていることを確認します。
docker
コマンドが使用できるかどうか確認します。
PowerShell
を起動してdocker version
コマンドを実行し、バージョンが表示されるかどうか確認します。
同じくUbuntu
を起動してdocker version
コマンドを実行し、バージョンが表示されるかどうか確認します。
これで、WindowsでDocker
が使用できるようになりました!
3. VSCoceの拡張機能 Remote-Containers を使って、Goの開発環境を構築する
最後に、Docker
コンテナ内でGo
の開発を「快適に」行うための準備をしていきます。
Docker
コンテナで開発する際のメリットとしては以下のようなものがあります。
- 開発に必要な手順が記載されている
Dockerfile
があれば、コンテナを起動するだけですぐに開発できる環境が整います。 - チーム内に
Dockerfile
を配布すれば、チーム全員が同じ環境で開発することができます。 - ランタイムやツールのインストールなどをする必要がないので、ホスト環境を汚しません。
Remote-Containers
を使えば、上記のメリットに加えて、VSCode
で開発作業が行えるようになるので、コードの編集はもちろん、インテリセンス、構文チェック、定義ジャンプ、デバッグなどの豊富な支援機能も使えるようになり、コンテナ内での開発が非常にスムーズになります。
それでは早速やっていきましょう。
3-1. VSCoceの拡張機能 Remote Developmentのインストール
まず、VSCode
の拡張機能に、Remote Development
をインストールします。
こちらはRemote-WSL
とRemote-Containers
とRemote-SSH
のセットになっています。
3-2. VSCodeをWSL(Ubunt)から起動する
次に、Ubuntu
を起動します。
mkdir
でgo-sample
フォルダを作成し、cd
で作成したフォルダに移動してから、code .
コマンドでVSCode
を起動します。
すると、VSCode
がWSL(Ubuntu)
のgo-sample
フォルダを開いた状態になります。
3-3. Dockerfileの作成
次に、go-sample
直下に.devcontainer
というフォルダを作成します。
.devcontainer
フォルダ内に、Dockerfile
という名前のファイルを作成します。
内容は以下の通りにします。
goのバージョンは1.13.15にしてますが、1.14系やlatestでも問題ないです。
go getでインストールしているのはGo開発で必要なツール群です。
※コンテナをリビルドする度にインストールするのが面倒だったので、Dockerfile内に書きました。もっと良いやり方があったら教えてください!
FROM golang:1.13.15
RUN go get -v -u \
github.com/mdempsky/gocode \
github.com/uudashr/gopkgs/v2/cmd/gopkgs \
github.com/ramya-rao-a/go-outline \
github.com/acroca/go-symbols \
golang.org/x/tools/cmd/guru \
golang.org/x/tools/cmd/gorename \
github.com/cweill/gotests/... \
github.com/fatih/gomodifytags \
github.com/josharian/impl \
github.com/davidrjenni/reftools/cmd/fillstruct \
github.com/haya14busa/goplay/cmd/goplay \
github.com/godoctor/godoctor \
github.com/go-delve/delve/cmd/dlv \
github.com/stamblerre/gocode \
github.com/rogpeppe/godef \
golang.org/x/tools/cmd/goimports \
golang.org/x/lint/golint \
golang.org/x/tools/gopls
3-4. devcontainer.jsonの作成
同じく.devcontainer
フォルダ内にdevcontainer.json
という名前のファイルを作成します。
内容は以下の通りにします。
settingsで設定、extentionsで拡張機能を指定できるので、お好みでどうぞ。
今回はGoの拡張機能をインストールして、設定をちょっと変えています。
エディタの環境まで共有できるのですごく便利ですね!
{
// VSCodeに表示されるワークスペース名
"name": "go-sample",
// Docker buildを実行するディレクトリ。devcontainer.jsonファイルからの相対パスで設定します。
"context": "..",
// コンテナの内容を定義するDockerfileのパス。devcontainer.jsonファイルからの相対パスで設定します。
"dockerFile": "Dockerfile",
// コンテナ側のVSCodeの設定値(setting.json)を変更したい場合、設定します。
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"go.formatTool": "goimports",
"go.useLanguageServer": true,
},
// コンテナ側のVSCodeに拡張機能をインストールする必要がある場合、拡張機能のIDを配列で設定します。
"extensions": [
"golang.Go"
]
}
3-5. Remote-Containersでコンテナにリモート接続する
次に、左下にある>< WSL: Ubuntu
をクリックし、Remote-Containers: Reopen in Container
を選択します。
VSCode
が再読込され、コンテナ内で起動します。
先程WSL(Ubuntu)
側で作成したフォルダ/ファイルがマウントされているのがわかります。
※初回はコンテナの作成に時間がかかりますが、次回からはもう少し早く起動すると思います。
ターミナルでBash
を起動し、go version
を実行します。
Go
のバージョン1.13.15
がインストールされていることを確認できます。
左下の歯車アイコンから設定を開き、@modified
と入力して変更した設定のみを表示します。
devcontainer.json
のsettings
で記載した内容が、リモート側のVSCode
設定に反映されていることを確認できます。
拡張機能はローカルにインストールするものとリモート側にインストールするものとで管理が分かれます。
devcontainer.json
のextensions
で設定したGo
の拡張機能がリモート側にインストールされていることを確認できます。
Dockerfile
でインストールするよう設定したGo
のツール群もインストールされています。
Docker Desktop
でもイメージが作成されていることが確認できます。
3-6. コンテナ内でのGo開発(hello world)
環境が整ったので、コンテナ内でGo
のhello world
を作ってみます。
ワークスペース直下にmain.go
という名前のファイルを作成します。
内容は以下の通りにします。
コピペでなく自分で入力すると、インテリセンスやスニペットなどの支援機能が効いていることが実感できると思います。
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
ターミナルでBashを開き、go run main.go
を実行します。hello world
と出力されれば成功です!
デバッグもやってみます。
main.go
のソース上でfmt.Println("hellow world")
にブレイクポイントを設定し、F5
キーを押します。
しばらくするとデバッグが実行され、設定したブレイクポイントで止まります。
デバッグツールバーのステップオーバーをクリックするか、F10
キーを押すと次のステップへ進みます。
fmt.Plintln
が実行されて、デバッグコンソールにhello world
を出力されることが確認できます。
これでGo
のデバッグが出来るようになりました!
※デバッグを終了させる場合は再度F5
キーを押してください。
3-7. コンテナへのリモート接続を終了する
コンテナへのリモート接続を終了させる場合は、左下の>< Dev Container
からリモート接続を終了する
を選択するか、右上の×
ボタンでVSCode
を閉じてください。
3-8. コンテナへのリモート接続を再開する
再度コンテナへのリモート接続をする場合は、WSL(Ubunt)
でgo-sample
フォルダを開き、左下の>< WSL: Ubuntu
からRemote-Containers: Reopen in Container
を選択してください。
初回起動では32.373秒かかりましたが、2回目は18.217秒で起動できました。
3-9. (おまけ)Windowsから直接Remote-Containersでコンテナにリモート接続する
今回はWSL(Ubuntu)
内にソースコードを配置して、WSL(Ubuntu)
からVSCode
のRemote-Containers
でコンテナを起動しましたが、Windows
上にソースコードを配置して、Windows
からコンテナを起動することもできます。
やり方はWSL(Ubuntu)
の時と同じで、3-3
~3-5
の手順をWindows
上で行うだけです。
ソースコードはWindows
で管理したいよ!っていう方はその方法でも良いかもです。
初回起動では39.594秒かかりました。WSL(32.373秒)より若干遅い?です。
注意点としては、Windows
からコンテナを起動すると、Docker Desktop
が以下の警告を表示します。
Docker Desktopは、WindowsファイルをWSL2コンテナーに共有したことを検出しました。これはパフォーマンスが低下する可能性があります。
https://docs.docker.com/docker-for-windows/wsl/#best-practices
上記URLのDocker Desktop WSL2 Backend
のベストプラクティスにもあるように、Linuxファイルシステムからマウントされるとパフォーマンスが大幅に向上するようです。Windowsファイルシステムからコンテナを起動するのは避けるように、ともあるので、気になる方はWSL
でソースコードを管理したほうがよさそうです。
まとめ
WSL2
とDocker Desktop for Windows
とVSCode
の相性が良く、Windows
でもDocker
開発がスムーズに行えるようになってきました。
Dockerfile
で開発環境を共有できるのはもちろんですが、devcontainer.json
でVSCode
の設定や拡張機能まで共有できるのもいいですね!
※Go
はまだいいですが、React
やVue
などのフロントエンドの開発だとESLint
とPrettier
の設定などでかなり労力を持っていかれるので、、、
これからは開発で積極的に取り入れていきたいと思います!