Docker Desktop無しでLinux/Windowsコンテナ共存環境を作る

## 何をやったのか
今更ですが、Dockerが気になっておりまして、いろいろネットも調べてみたのですが、どうもイメージがつかめず。ということで、自分の端末に触れる環境を作ってみました。

Docker Deaktopは諸事情により使用できず、しかし、Windows Containerも評価したい、ということで、以下のページを参考に構築を行っています。

[Running Windows and Linux containers without Docker Desktop](https://lippertmarkus.com/2021/09/04/containers-without-docker-desktop)

ぶっちゃけ、今から記載するこの記事は「上のページを実際にやってみたログ」でしかないので、あまり学びとかはないと思います。すみません。

また、Windows側の環境構築方法(Docker Desktopを使用しない)は公式の手順ではないので、将来的には使えなくなるリスクがあります。


【2025/6/10追記】
以下のページを参考に、Windows側でDocker Composeを使用できるように手順を修正しました。

https://zenn.dev/0_0/articles/40dd471fffc8b4


## 全体構成
全体構成は以下の通りです。
![configuration2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/944269/cf0bd8bd-0431-e026-5c4c-db40111d7c02.png)

- ベース環境には手持ちの端末(Windows 11 Pro)を使用しています
- 通常のLinuxベースのコンテナに加えて、Windowsコンテナも動かします
- 有償になってしまったDocker Desktopは使用しません
- LinuxベースのDockerのホストはWSL2上に構築します

## WSL2のインストール
Powershellで以下を実行。このコマンド一発で、機能の有効化だけでなく、Linux OS(Ubuntu)イメージの展開まで行われます。

参考
[WSL2 のインストールとアンインストール](https://qiita.com/zakoken/items/61141df6aeae9e3f8e36)
[WSL を使用して Windows に Linux をインストールする方法](https://learn.microsoft.com/ja-jp/windows/wsl/install)

```powershell:
wsl --install
```

再起動後、UbuntuのユーザのID/パスワードを設定


## Ubuntuの配置先を変更
これは実施しなくてよいが、OSイメージの配置先が不明確なのは気持ち悪かったので、明示的にDドライブへ移動。

参考
[Ubuntu(WSL2)をCドライブからDドライブへ引越す](https://zenn.dev/shittoku_xxx/articles/066cfd072d87a1)

### イメージの移動
Powershellから以下を順に実行。「D:\wsl\wsl001」が格納先になる。
```powershell
wsl --terminate Ubuntu
cd D:\wsl\wsl001
wsl --export Ubuntu Ubuntu.tar
wsl --unregister Ubuntu
wsl --import Ubuntu D:\wsl\wsl001 D:\wsl\wsl001\Ubuntu.tar
```

### 初期ユーザの調整
上の手順の実施後、初期ユーザーがrootになるので、元に戻す。 
Ubuntuへログインして/etc/wsl.confの末尾に以下を追加。 
「rabut」の部分に初期ユーザの名称を指定する。 
```:/etc/wsl.conf
[user]
default=rabut
```

Ubuntuを再起動
```Powershell:
wsl --terminate Ubuntu
wsl --list -v # Stoppedを確認
  NAME      STATE           VERSION
* Ubuntu    Stopped         2
wsl # Ubuntuのプロンプトが起動すればOK
```
```shell
rabut@pc001:/mnt/c/Users/rabut$ whoami
rabut
```
※rabutが初期ユーザの場合

### メモ
ちなみにデフォルトの格納先は、以下のような場所らしいです。
C:\Users\\\<User Name>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState


## Dockerエンジン(Linux側)のインストール
UbuntuにDockerエンジンをセットアップします。

参考
[WSL2でDocker環境構築(Docker Desktop有料化対策](https://qiita.com/haveAbook/items/0d0ae20a19214f65e7cd)
[Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)

### 古いパッケージが存在しないことの確認
Ubuntuのコンソールから以下を実行。何も返ってこないことを確認。
```shell
dpkg -l | grep docker
dpkg -l | grep container
dpkg -l | grep runc
```

### Dockerのaptリポジトリのインストール
Ubuntuのコンソールから以下を順に実行。
```shell
# Dockerのサイトの公開鍵をインストール
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Dockerリポジトリをaptに追加
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 確認
cat /etc/apt/sources.list.d/docker.list
# 手元の環境では以下のように返ってきた
# deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu   jammy stable

# 更新(反映)
sudo apt-get update
```

### Docker関連パッケージのインストール
Docker関連パッケージのインストール
```shell
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
### 動作確認
Dockerが使えるようになったことの確認
```shell
sudo docker run hello-world
```

今回のセットアップでは以下のように返ってきた。結構メッセージが長い。
```shell
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:94323f3e5e09a8b9515d74337010375a456c909543e1ff1538f5116d38ab3989
Status: Downloaded newer image for hello-world:latest

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/
```


## Dockerエンジン(Windows側)のインストール
Windows側のDockerをセットアップします。

参考
[Running Windows and Linux containers without Docker Desktop](https://lippertmarkus.com/2021/09/04/containers-without-docker-desktop)

### Windowsの機能の有効化
コマンドプロンプトを特権で起動し、Powershellから以下を実行。手持ちの環境ではHyper-Vを有効化済みだったため、containersのみ実行。実行後、再起動を要求されるので、再起動。
```powershell:
Enable-WindowsOptionalFeature -Online -FeatureName containers -All
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
```

### Docker(Windows)関連ファイルのインストールとサービス作成
バイナリ資産を入手して、セットアップします。

1. 以下からバイナリ資産をダウンロード
https://download.docker.com/win/static/stable/x86_64/
おそらく、最新版を落とせばよいと思われる。2025/06/10成時点では「docker-28.2.2.zip」。

2. 落としたzipファイルを任意の場所に展開
参考ページは「C:\docker」に展開していますが、私は個人的の好みで「C:\Program Files\docker」に展開。
3. 展開先フォルダにPATHを通す
参考ページのスクリプトが若干気持ち悪かった(これ、システム環境変数のPATHにユーザのPATHが混入しないか？)ので、手動で設定(※)。端末を再起動。
(※)コントールパネル→システム→システムの詳細設定→環境変数 からシステム環境変数に追加

4. サービスの登録
コマンドプロンプトを特権で起動し、以下を実行。
```powhershell
dockerd --register-service
```



### 動作確認
Powershellから以下を実行
(※サービスは自動起動で登録されるので、2回目以降、Start-Serviceは不要)
```powershell
Start-Service docker
docker run hello-world
```
以下のように返ってきました。Linuxより、若干時間がかかります。
```shell
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
a8c295c425a9: Pull complete
20c981690370: Pull complete
907ea000aac2: Pull complete
Digest: sha256:94323f3e5e09a8b9515d74337010375a456c909543e1ff1538f5116d38ab3989
Status: Downloaded newer image for hello-world:latest

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.
    (windows-amd64, nanoserver-ltsc2022)
 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 a Windows Server container with:
 PS C:\> docker run -it mcr.microsoft.com/windows/servercore:ltsc2022 powershell

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/
```

### Docker Compose(Windows側)のセットアップ【2025/06/10追記】
Docker Composeの機能をWindows側に追加します。

参考
[WSLもDocker Desktopも使わずにDockerをWindowsでやってみる](https://zenn.dev/0_0/articles/40dd471fffc8b4)

1. 実行ファイルのダウンロードと格納

    以下から最新バージョンのDocker Composeのダウンロードして格納します。2025/06/10時点の最新バージョンは「v2.37.0」でした
    - ダウンロードサイト：https://github.com/docker/compose/releases
    - 入手ファイル：docker-compose-windows-x86_64.exe
    - 格納先：C:\ProgramData\docker\cli-plugins\docker-compose.exe
      ※ファイル名から「windows-x86_64」を削除して格納してください  
      
2. サービス再起動
    コマンドプロンプトから以下を実行。
    ```
    net stop docker
    net start docker
    ```

3. 動作確認
コマンドプロンプトから以下を実行して結果を確認。
    ```
    docker compose version
    ``` 
    実行例
    ```
    C:\>docker compose version
    Docker Compose version v2.37.0
    ``` 

## ホストからLinuxのdockerを操作できるようにする
Linux側のdockerを、WSLのコンソールを起動せずに、ホストからPowershellで操作できるようにします。

### Linux側のセットアップ
デーモンの有効化
```shell
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
```
ローカルホストにdockerを公開
```shell
sudo cp /lib/systemd/system/docker.service /etc/systemd/system/
sudo sed -i 's/\ -H\ fd:\/\//\ -H\ fd:\/\/\ -H\ tcp:\/\/127.0.0.1:2375/g' /etc/systemd/system/docker.service
sudo systemctl daemon-reload
sudo systemctl restart docker.service
```

### Windows(ホスト)側のセットアップ
ホストからPowershellで以下を実行。コンテキストを登録。
```powerhsell
docker context create lin --docker host=tcp://127.0.0.1:2375
```

### 動作確認
ホストからPowershellで以下を実行。
```powerhsell
docker -c lin version
```
以下のように返ってくる。(ServerのOS/Arcがlinux/amd64になっている)
```
Client:
 Version:           27.0.2
 API version:       1.46
 Go version:        go1.21.11
 Git commit:        912c1dd
 Built:             Wed Jun 26 18:48:14 2024
 OS/Arch:           windows/amd64
 Context:           lin

Server: Docker Engine - Community
 Engine:
  Version:          27.0.2
  API version:      1.46 (minimum version 1.24)
  Go version:       go1.21.11
  Git commit:       e953d76
  Built:            Wed Jun 26 18:47:16 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.18
  GitCommit:        ae71819c4f5e67bb4d5ae76a6b735f29cc25774e
 runc:
  Version:          1.7.18
  GitCommit:        v1.1.13-0-g58aa920
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```

## 所感など
Docker Desktopなしで環境構築、みたいなキーワードでググると、WSL2+Linuxでできるよ、という記事がいっぱいヒットするのですが、それだとWindowsコンテナが実行できないのですよね。
で、やっと探し当てたページが、めっちゃザックリ記載だったので、少し詳細なログを残してみました。
もう少してこずるかと思ったのですが、案外あっさり構築できて、元のページがザックリ記載だったのも納得です。まあ、セットアップの手間を省けるのがDockerの大きなメリットなので、それ自身のセットアップも簡単にできるようになっているのですかね。

さて、この環境を使って、いろいろ評価しようと思っているのですが、どれだけ時間取れるかな…。
とりあえず今回は以上です。