WSLにDocker+VS Codeを導入する

[目次に戻る](https://qiita.com/Lintaro/items/c82c6cb29f3447c2ffdc)

WSL環境下にDocker+VS Codeを導入する方法を説明します。
より正確には、Windows環境にVS Codeを導入し、リモート接続でWSL上のLinux（Ubuntu）にアクセスし、WSL環境内でDockerを立ち上げ、Dockerコンテナにリモート接続して開発を行う、という状況を想定します。



# 前提
WSLは導入済みとします。まだセットアップが終わっていない場合は下記の記事を参考に導入してください。

https://qiita.com/Lintaro/items/855b02164978140dee11



# 使う道具
 - WSL2 (※重要 wsl1では不具合がある）
 - Docker
 - VS Code
   - ExtensionsRemote Development

# VS CodeをWindowsにインストール
下記からダウンロードして、インストール。特に躓くところは無いと思います。

https://code.visualstudio.com/download



# WSLにDockerをインストール

公式ドキュメントを参考にインストール。

https://docs.docker.com/engine/install/ubuntu/

Docker Composeが必要な場合は、ついでにDocker Composeもインストール。

https://docs.docker.com/compose/install/

続いて、WSL上で下記を実行。WSL上でdockerコマンドを使えるように、ユーザーをdockerグループに所属させる。

```shell
sudo usermod -aG docker $USER
```

試しに下記を実行して、「Hello from Docker!」が表示されれば成功です。

```shell
docker run hello-world
```

まれに、docker psなどがpermission deniedになる場合がありますが、WSLを再起動すれば解決します。
PowerShell側で、

```PowerShell
wsl --shutdown
```

としてWSLをシャットダウンし、スタートメニューなどからWSLを再度起動すればOK。


# Dockerコンテナにリモート接続する
基本的な設定は以上ですが、ここから実際にDockerコンテナにVS Codeからリモート接続して開発を行う方法を説明します。


## WSL上のUbuntuにVS codeでリモート接続する
この先、Dockerfileの編集などで、WSL上のUbuntu（※Dockerコンテナではない）にVS Codeからアクセスできると楽です。

WSLのプロンプトで以下を実行すると、自動でVS Code Server for Linuxがインストールされ、リモート接続されたVS Codeが自動で立ち上がります。

```shell
code .
```

今後も、WSL上のUbuntuにVS Codeでアクセスしたいときは、上記のコマンドでアクセスできます。


##  VS CodeにDev Containersをインストール

VS Codeの拡張機能であるDev Containers（ms-vscode-remote.remote-containers）をインストール。

## Dockerfileの作成
もし既にDockerの経験があり、使いたいDockerfileがあるなら、それを用いてOK。
とりあえず試しに使えるものがあればいい、という場合に向けて説明します。

以下のようなディレクトリ構成を想定します。WorkingDirectoryは現在の作業フォルダ（カレントディレクトリ）です。

```
WrokingDirectory
  ├─ Dockerfile
  └─ main.py
```

:::note info
今後、devcontainer.jsonやdocker-compose.yml, requirements.txtなどを扱う事を考えると、下記のようにすべきです。

```
WrokingDirectory
  ├─ .devcontainer
  │　└─ Dockerfile
  └─ main.py
```

ただし、このような構成でVS CodeからDockerfileを読み込ませるには、.devcontainerをワーキングディレクトリとせねばなりません。
上記の構成でWorkingDirectoryから.devcontainer下のDockefileを読み込ませるには、devcontainer.jsonによる設定が必要です。しかし、本稿のスコープを外れるため、敢えてDockefileをワーキングディレクトリ直下に配置しています。
devcontainer.jsonによるRemote Development（Dev Containers）の制御については、別の記事に取りまとめる予定です。下記の目次からご参照ください。

https://qiita.com/Lintaro/items/c82c6cb29f3447c2ffdc

:::

WorkingDirectoryで、上述の ```code .``` を実行すると、WorkingDirectoryをワーキングディレクトリとしてVS Codeが立ち上がります。
Dockerfileを以下のような内容にします。

```Dockerfile: Dockerfile
FROM python:3.9-slim-buster
```

main.pyを以下のような内容にします。

```python: main.py
print('Hello! World!!')
```


## Dev Containerでコンテナに接続
WSL上のWorkingDirectoryで、 ```code .``` コマンドによりVS Codeを起動します。
自動的にWSL上のUbuntuにリモート接続した状態になっているはずです。
左下の接続先を確認すると、下図のようにWSL: Ubuntuとなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378712/3e740eb8-37e8-8236-8260-102577609fbc.png)


ここから、Dockerfileに基づいてビルドされたDockerコンテナに接続していきます。
上記、WSL: Ubuntuとなっている箇所をクリックすると、下記のようなメニューが開きます。
Reopen in Containerをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378712/0d8a4a24-6ff8-ea1f-f964-73d2988071a9.png)

From Dockerfileをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378712/1d34a50d-e2bd-f854-35f6-6229b6e19581.png)

Select Additional Featuresは特に何も選択せずにOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378712/641fe01a-5895-30f9-2d14-1afab20971ec.png)

最初はDockerイメージの取得やビルドが行われるため、多少時間がかかります。

成功すると、新たなVS Codeが立ち上がります。
左下の接続先も、「Dev Container: Existing Dockerfile」などとなっており、TERMINALもDockerコンテナ内のプロンプトに変わっています。



# 次回以降の接続方法

次回以降は、ワーキングディレクトリで ```code .```したあと、上記と同様の手順でReopen in ContainerすればDockerコンテナにリモート接続できます。

補足として、DockerコンテナはReopen in Containerしたときにコンテナが立ち上がり、リモート接続しているVS Codeを閉じたときにコンテナが終了します。
サーバー開発などで持続的にコンテナを起動しておきたい場合は、VS Codeを閉じないようにするか、Dockerからコンテナを立ち上げ、コンテナ内にVS Code Server for Linuxを入れ、コンテナ内から```code .```でVS Codeのリモート接続を行う、といった方法を取ってください。

[目次に戻る](https://qiita.com/Lintaro/items/c82c6cb29f3447c2ffdc)



# 参考

https://zenn.dev/kcabo/articles/c4f9b7fecc503a

https://zenn.dev/canard0328/articles/wsl2-docker-vscode