WSL2 Docker VSCodeでJava開発環境を構築

# WSL2 Docker VSCodeでJava開発環境を構築

WSL2とDockerとVSCodeで開発環境を作るのがホットな話題だったので試してみたのですが、
作ったものの開発環境の動作が重すぎてドはまりしました。
オチとしては開発ソースを軽量Linuxのフォルダ内でなくWindowsフォルダにおいていたのが原因でした。
自分への戒めのため手順を残しておきます。


## WSL2のインストール

###  Linux 用 Windows サブシステムを有効にする

管理者として PowerShell を開き、以下を実行します。

~~~powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
~~~

### 仮想マシンの機能を有効にする
管理者として PowerShell を開き、以下を実行します。

~~~powershell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
~~~
マシンを再起動します。

### Linux カーネル更新プログラム パッケージをダウンロードする

1. 最新のパッケージをダウンロードし、インストールします。  
[x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)


### WSL 2 を既定のバージョンとして設定する

PowerShell を開いて次のコマンドを実行し、新しい Linux ディストリビューションをインストールする際の既定のバージョンとして WSL 2 を設定します。

~~~powershell
wsl --set-default-version 2
~~~

### 選択した Linux ディストリビューションをインストールする

1. [Microsoft Store](https://aka.ms/wslstore)を開き、希望する Linux ディストリビューションを検索し、選択します。
2. ディストリビューションのページで、[入手] を選択します。ここではUbuntu 20.04 LTSを入手します。
3. Ubuntu 20.04LTSを起動し、ユーザー名・パスワードを入力します。
4. コマンド`sudo apt-get update`でUbuntu を更新しておきます。

### WSLのフォルダを確認

WindowsからWSLのLinuxファイルシステムにはエクスプローラーに以下のパスを入力することでアクセスできます。

~~~
\\wsl$
~~~

Ubuntu20.04LTSの場合は以下になります。

~~~
\\wsl$\Ubuntu-20.04
~~~

WSL+Dockerを利用して開発を行うときは、ソース等をこの配下に配置します。

またWSLからWindowsのフォルダを参照するとWSLのターミナルからは
下記とおりになります。

~~~bash
/mnt/c/
~~~

※こちらですが、この配下にソースを置いておくとLinuxシステムからWindowsシステムへの参照が行われるため、ファイル I/O が異常に遅くなりますの気を付けてください。

###  WSLのリソースを制限
WSLはデフォルトだとホストマシンの物理メモリの80%を確保するようで、
ホストのメモリ不足が発生する可能性があるので、設定を変更します。
以下のファイル（なければ新規作成）に設定を記述します。
`%USERPROFILE%\.wslconfig`

記述内容は以下になります。

~~~
[wsl2]
memory=4GB
swap=0
processors=2
~~~
くわしくは[WSL コマンドと起動構成](https://docs.microsoft.com/ja-jp/windows/wsl/wsl-config#configuration-options)を参照

設定を反映させるにはWSLを再起動します。

PowerShellから以下のコマンドを実行し、WSLのターミナルを立ち上げなおすことで再起動されます。

~~~powershell
wsl --shutdown
~~~

起動中のWSLを確認するにはPowerShellで以下のコマンドを実行します。

~~~powershell
wsl -l -v
~~~




## Dockerのインストール・設定

### インストール
[Docker Desktop](https://www.docker.com/products/docker-desktop)をインストール
インストール時に`Enable WSL 2 Windows Features`のチェックをいれること

### 設定

Docker Desktopを起動し、タスクバーのDockerのアイコンを右クリックし`setteings`を起動

- Generalにて`Use the WSL 2 based engine`にチェックがはいっていること
- Resourcesにて`Enable integration with my default WSL distro`にチェックがはいっていること。  
※PowerShellで`wsl -l`コマンドで表示したリストで規定になっているDistroからDockerDesktopを使用できる。

##  VSCodeの設定

### 環境変数の設定
Windowsの環境変数のPATHに以下のようにVScodeのbinフォルダを設定しておくと
WSLからコマンドでVSCodeを起動できるようなります。
`C:\app\VSCode\bin`

### 拡張機能のインストール
[Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)をインストールします。


Remote Development は複数の拡張機能が含まれますが、
今回は特にRemote - Containerを使用します。
他には以下のような拡張機能もインストールされます。

- Remote - WSL
- Remote - SSH


### VSCodeの起動
- WindowsTerminal or Ubuntuターミナルを起動
- コマンド`cd ~`を実行してホームフォルダに移動
- コマンド`pwd`でホームフォルダのパスを確認  
WSL 上では `/home/ユーザー名`  になります。  
Windows上 では`\\wsl$\Ubuntu-20.04\home\ユーザー名`になります。  
- 任意のフォルダを作成し移動

~~~bash
mkdir dev_root
cd dev_root
~~~
- VsCodeの起動
 
~~~bash
code .
~~~

### Remote コンテナの作成

`ctrl + shift + p` を押し、
`remote-containers: Open Folder in Container`を入力

下記通りプロンプトが表示されるのでそれぞれ選択を行う

1. フォルダを選択
1. Dockerイメージを選択→ javaを選択
1. Javaバージョンを選択→11を選択
1. ビルドツールを選択→maven gradle nodeはお好みで選択

### Javaプロジェクトの作成

VsCodeのターミナルから
spring boot initializrでプロジェクトのひな型を作成

~~~bash
curl https://start.spring.io/starter.zip \
       -d dependencies=web \
       -d javaVersion=11 \
       -o demo.zip
~~~

プロジェクトのひな型を解凍

~~~
unzip demo.zip
~~~

DemoApplication.javaを下記通り編集

~~~java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@GetMapping("/")
	public String index(){
		return "hello World";
	}

}
~~~

`F5`キーを押し、デバッグ実行を行い[http://localhost:8080/](http://localhost:8080/)にアクセスする


## Remote-Containerについての補足

Remote-Containerを利用すると
`.devcontainer`フォルダが作成され、そこに以下の二つのファイルが作成されます。

- devcontainer.json
  こちらにはビルドするDockerファイルやDocker Composeファイルを指定したり、
  コンテナのVsCodeの設定(java.homeとか)やインストールしたい拡張機能(spring-boot-extention-pack等)を記述することができます。

- Dockerfile
  コンテナをビルドするためのDockerファイルになります。今回は拡張機能（MS）が用意しているDockerイメージを使用しましたが、
  Docker Hub等にアップされている自分の好きなDockerイメージに変更することが可能です。


この記事は以下の情報を参考にして執筆しました。

- [Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
- [Windows Subsystem for Linux 2のメモリ管理を詳しく見る](https://ascii.jp/elem/000/001/981/1981180/)