Windows+WSL2+Docker+VSCODEで使い捨て開発環境を構築するまで～前編～

# 背景
プログラミング学習を進める中で、PythonやNodeなどのライブラリやツールをローカル環境に導入するたび、煩雑なバージョン管理に悩まされることが多々ありました。バージョン管理ツールの導入も検討しましたが、試しに触れる程度の言語にそこまで手間をかけるのは少し気が進まないというジレンマがあり、モヤモヤしていました。

そのため本記事（および、後編）では、Windows上でLinux環境(WSL)を使い、その上にDockerコンテナを立ち上げ、試したいツールを気軽にインストールする方法を実践してみました。さらに、コンテナ操作をVSCodeでできるようにします。これによりうまくいかなくても、不要になったらそのままコンテナごと捨てられるという環境できるあがります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/dd592a29-3158-f0cf-d61a-1b53a0e3e605.png)
図：使い捨て開発環境のイメージ図


# 補足
今回記載する方法は、次のURLで紹介されている「[Docker Desktop WSL 2 backend on Windows](https://docs.docker.com/desktop/wsl/)」とは異なります。

Docker社は、2022年からDocker Desktopの商用利用を有償化したため、この記事では、WSL2のLinux環境上に直接Dockerエンジンを稼働させる方法について説明します。この手法により、Docker Desktopをインストールせずに、Dockerの環境を構築することが可能です。

（ライセンス上問題なくDocker Desktopが利用できる方は、Docker Desktopを利用すればもっと簡単に構築できると思います。）

# 今回記事のゴール
コンテナの中からPythonコードを実行するまで
（VSCodeからの操作はまた次回）

# 実施した環境
"★"は、手順を実施した結果インストールしたもの

## ローカルPC
    # OS
    OS:                     Microsoft Windows 11 Pro
    OS バージョン:           10.0.22621 N/A ビルド 22621
    # パワーシェル
    PS Version:             5.1.22621.4249
    
    # Docker関連
    Docker Version ★:         27.3.1
    Docker Compose version ★: 2.29.7

## WSL2(Dockerコンテナを実際に稼働させる母艦になるLinux)
    OS:                     Ubuntu 24.04.1 LTS
    Docker Version ★:         27.3.1
    docker-compose version ★: 1.29.2, build unknown

## 作ったコンテナ
     OS ★:                     Debian GNU/Linux 12 (bookworm)
    Python ★:3.13.0

# 環境構築手順

## 1.前提
- WSL2の有効化が完了していること@ ローカルPC 
    - 私の環境だと対応なしでWSLのバージョン2でUbntuが導入できましたが、OSバージョンにより結構ここははまることもあるみたいです。 ご注意ください。[Windows Subsystem for Linux のトラブルシューティング](https://learn.microsoft.com/ja-jp/windows/wsl/troubleshooting)  

## 2.WSL2コマンドでLinuxをインストール@ ローカルPC

### 2-1.インストール
```powershell
wsl --install 
```
※ 上記コマンドは、ディストリビューションを引数に設定してないのでデフォルトでUbuntuがインストールされます
### 2-2.ID/PW設定
OS再起動後、ID/PWを設定を設定するターミナルが表示されたら、IDとPWを設定
（表示されなければスタートメニューよりUbuntuを選択)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/f3a400b8-b098-ca4c-e8da-fe5d646b2fbf.png)

## 3.wsl.confの設定@ WSL
WSL上でDockerを動作させるためには、systemdというLinuxのサービスマネージャが必要です。通常、WSL2環境ではsystemdがデフォルトで無効になっています。そのため、WSLの設定ファイルで有効化する必要があります。

### 3-1./etc/wsl.confの新規作成@ WSL
以下のコマンドを実行し、wsl.confファイルを作成または編集します。
```bash
sudo nano /etc/wsl.conf
```
### 3-2./etc/wsl.conf記載内容@ WSL
```conf:/etc/wsl.conf
[boot]
systemd=true
```

### 3-3.WSLの再起動@ ローカルPC
```powershell
wsl --shutdown
wsl
```

## 4.Dockerをインストール@ WSL
### 4-1.Dockerを導入します。
参考：https://docs.docker.jp/linux/step_one.html
```bash
$ sudo apt-get update
$ curl -fsSL https://get.docker.com/ | sh
$ sudo service docker status
#以下、statusコマンド実行後、起動していなかった場合実施
$ sudo service docker start
```

### 4-2.Dockerの動作確認
```bash
$ sudo docker run hello-world
```

無事に導入ができていれば、以下の出力がコンソールに確認できます。
```bash
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
 ```

なおご覧いただきました、上記のhello-worldはテスト用のコンテナです。イメージおよびコンテナが残っているので、消してしまいましょう。

```bash
$ sudo docker rm $(sudo docker ps -a -q --filter "ancestor=hello-world")
$ sudo docker rmi hello-world
```

### 4-3.Docker-Composeも導入しておきます。
Docker-Composeは、コンテナの扱ううえで必須ではないですが、複数のコンテナを一括管理するためのツールです。次のようにインストールします。

```bash
$ sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep tag_name | cut -d '"' -f 4)/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose -v
```

## 5.sudoなしでdockerコマンドが実行できるようにする@ WSL/ローカルPC
Dockerはroot権限で動作するため、通常のユーザでsudoなしに使うにはdockerグループに追加する必要があります。

### 5-1.Dockerグループにユーザーを追加@ WSL
Dockerデーモンへのアクセスは通常、sudo権限を持つか、dockerグループのメンバーである必要があります。以下のコマンドで、wsluserをdockerグループに追加します。
```bash
sudo usermod -aG docker $USER
```

### 5-2.WSLの再起動@ ローカルPC
```powershell
wsl --shutdown
wsl
```

## 6.DockerとDocker-Composeの作成@ ローカルPC
PythonでHelloworldを表示するため準備として、簡単なコードを用意します。

ローカルエクスプローラーで`\\wsl.localhost\Ubuntu\home\{ユーザー名}`へアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/1e1eb43a-83f9-6002-aa9a-f358aba26c12.png)

エクスプローラー上で右クリックし、「新しいフォルダー」を選択して、hello-dockerという名前のフォルダを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124955/5555f564-0e44-1031-c3ea-1a101b0a1f6d.png)

作成したフォルダに移動し、次の手順でファイルを作成していきます。
```
home\wsluser\hello-docker
│
├── Dockerfile
├── app.py
└── docker-compose.yml
```

```dockerfile:Dockerfile
# Pythonの最新版を使用
FROM python:latest

# コンテナ内の作業ディレクトリを設定
WORKDIR /usr/src/app

# カレントディレクトリの全ファイルをコンテナ内にコピー
COPY . .

# コンテナ起動時に実行するコマンドを指定
CMD ["python", "app.py"]
```
次に、Pythonのapp.pyに「Hello, World!」を表示するコードを記述します。
```python:app.py
# Hello, World!を表示するプログラム
print("Hello, World!")
```
最後に、docker-compose.ymlで、Docker Composeを使って簡単にビルド・実行できる設定を行います。
```yaml:docker-compose.yml
version: '3'
services:
  python-service:
    build: .
    container_name: hello-python-container
    tty: true
```

## 7.Dockerコンテナの起動@ WSL
WSLのターミナルを開き、作成したフォルダに移動します。
```bash
cd ~/hello-docker
docker-compose up --build
```

下記標準出力が出ていれば無事にコンテナが起動できました。

```:docker-compose up --buildの標準出力
~~~一部抜粋~~~
hello-python-container  | Hello, World!
hello-python-container exited with code 0
```

# まとめ
ここまでで、前半は終了となります。今回の手順では、WSL2上にDockerをインストールし、Pythonの「Hello, World!」を表示するシンプルなコンテナを実行するまでの流れを紹介しました。

以下が重要なポイントです。

* Docker Desktopを使わない利点
WSL2上でDockerエンジンを直接稼働させることで、商用利用の制限を回避できる。

* 使い捨て環境の利便性
コンテナは簡単に削除・再作成でき、環境構築の手間を最小限に抑えられる。

* 拡張性
他のプログラミング言語やツールも同様にコンテナで試せるため、導入による他の影響を気にせず利用でき、学習・開発の幅が広がる。

# 次回予告
後半の記事では、今回の環境をもとに、さらにVSCodeを活用してDockerコンテナ内での開発をさらに効率化する方法を紹介します。


# 追記（2025年1月19日）
[後編](https://qiita.com/kamiryo/items/a8807440ff780f5e16c9)も投稿しました。よければご覧ください。