Docker と WSL2
〜 Windows でも Docker 〜
+
2026-03-26 作成 福島
TOP > tips > docker-wsl2
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell | GBC | LLM ]

Docker とは

Docker(ドッカー) とは、機能を配布する手段です。
本来の使い方はこちらを参照してください。

Docker は、イメージとコンテナという 2 つの状態が存在し、それぞれプログラムプロセスとして読み替えることができます。
イメージはファイルであり、コンテナは実行状態のことです。
アプリケーションはファイルとして流通し、起動すると実行状態になります。
状態存在形態備考
イメージファイル実行前の状態: ダウンロードや手渡しなどで受け渡しできる。動作しなければ、ただのデータ。
コンテナプロセス実行中の状態: 何かの役に立っている状態。
(ちょっとウソが入っています。コンテナは正確にはリソースを分離する技術のことです)
Docker の開発環境には Linux、macOS、Windows があります。
また、イメージ (プログラム) の内容は Linux と Windows があり、
Linux コンテナはすべての環境で作成・実行できますが、
Windows コンテナは Windows でしか作成・実行ができません。
作成・実行可能な環境と使用割合 (本番環境ではありません)
開発環境Linux
コンテナ
Windows
コンテナ
使用割合     
Linux53%
macOS51%
Windows47%
The 2025 Docker State of Application Development Report による。
合計すると 100% を超過するが、これは開発者が複数の端末を使用していると予想される。
本稿は、Windows の Docker で Linux コンテナを動作させます*1
Windows で Linux コンテナを動作させる場合は WSL2 という Linux の実行環境が必要になります。
*1実務の本番環境は、ほぼすべてが Linux コンテナで構成されているため、これに合わせています。

WSL2 や Docker をそれぞれ単体でインストールするのは煩雑(めんどう)なので Docker Desktop で一度にインストールします。
Docker Desktop の GUI はネットワークを扱えないため、使用しません。
Windows の  ターミナル  で作業します。(スタートを右クリック - ターミナル)

動作環境
項目内容備考
基本ソフトWindows11 pro 25H2本稿記述時の最新版
DockerDocker Desktop v4.64.0本稿記述時の最新版
Docker Desktop は WSL2 を含む
Docker イメージAlmaLinux9コンテナは一般的な Linux で構成する
(Docker Desktop は KVM の Windows11 でも動作する)


1. 動作環境の確認

Windows の仮想化が有効かどうかを確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # WSL2 を起動できるか確認する
PS C:\> Get-ComputerInfo -Property "HyperVisorPresent"

HyperVisorPresent
-----------------
             True  ← True があること

PS C:\> exit 


2. Docker Desktop のインストール

2-1. インストーラをダウンロードする。
公式 Web ページから、Docker Desktop のインストーラをダウンロードする。
AMD64 と ARM64 が紛らわしいので注意すること。

 Windows 版のダウンロード - AMD64 ← こっち
 Windows 版のダウンロード - ARM64 

ファイル名は Docker Desktop Installer.exe だった。(623,857,584 バイト)
ARM64 版もファイル名が同じなので、さらに紛らわしい。
2-2. インストーラを実行する。
Docker Desktop Installer.exe を実行する。

 UAC では ボタンをクリックする。

 ⇓
  ボタンをクリックする。

 ⇓
 待つ (1~2 分間)

 ⇓
ボタンをクリックする。


この時点ではまだ Docker は使えない
2-3. Docker を使えるようにする。
Docker Desktop を初期化すると WSL2 がセットアップされ、Docker を使えるようになる。

 スタートから Docker Desktop を起動する。
Windows を再起動したときも Docker Desktop の起動が必要。

 ⇓
ボタンをクリックする。

 ⇓
Skip をクリックする。

 ⇓
かなり待つ。

 ⇓
GUI はしばらく使用しないのでウィンドウを閉じる。

Docker Desktop の GUI は (公式なのに) ネットワークの作成や管理ができない。
Portainer(CE) を使えば可能だが、本稿では触れない。
2-4. WSL2 を確認する。
この「docker-desktop」を利用して Docker コンテナが動作する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # docker 用のディストリビューションの存在を確認する
PS C:\> wsl --list 
Linux 用 Windows サブシステム ディストリビューション:
docker-desktop (既定値)   ← docker-desktop があること

PS C:\> exit 

2-5. サンプルで動作確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # 定番の Hello world を実行する
PS C:\> docker run hello-world 
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
17eec7bbc9d7: Pull complete     ← 最初は Pull (ダウンロード) になる
ea52d2000f90: Download complete
Digest: sha256:85404b3c53951c3ff5d40de0972b1bb21fafa2e8daa235355baf44f33db9dbdd
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/ PS C:\> exit
2-6. プロセスを確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # hello-world は表示するとすぐに終了するため、プロセスが見えない
PS C:\> docker ps 
CONTAINER ID IMAGE       COMMAND  CREATED        STATUS                    PORTS   NAMES              
 --- hello-world のプロセスは表示されない ---

PS C:\> # 終了したプロセスも確認
PS C:\> docker ps -a 
CONTAINER ID IMAGE       COMMAND  CREATED        STATUS                    PORTS   NAMES              
3abfde645278 hello-world "/hello" 7 minutes ago  Exited (0) 7 minutes ago          keen_brattain

PS C:\> exit 


3. Docker イメージの作成と動作確認

現在時刻を返すサーバ機能を作成してみる。
標準的な OS のコマンドだけを使用するため、プログラムは作成しない。

3-1. Docker イメージを作成する。
3-1-1. 定義ファイルを作成する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # イメージ作成用フォルダを作成する
PS C:\> mkdir -Force .\daytime\ 


PS C:\> # Dockerfile を作成する PS C:\> @" FROM almalinux:9-minimal # ncat をインストール RUN microdnf install -y nmap-ncat && microdnf clean all # リッスンポート (省略可。Docker Desktop では必須) EXPOSE 130 # ポート130で待ち受け、接続されたら現在時刻を返して終了する設定 # -lk: 待機を続ける, 130: ポート番号, -e: 接続時に実行するコマンド CMD ["ncat", "-lk", "130", "-e", "/usr/bin/date"] "@ | Out-File -Encoding utf8 .\daytime\Dockerfile PS C:\> exit
3-1-2. Docker イメージをビルドする。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # Docker イメージをビルドする
PS C:\> docker build -t daytime .\daytime\ 
[+] Building 12.3s (6/6) FINISHED                                                                  docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                               1.2s
 => => transferring dockerfile: 466B                                                                               0.6s
 => [internal] load metadata for docker.io/library/almalinux:9-minimal                                             3.1s
 => [internal] load .dockerignore                                                                                  0.3s
 => => transferring context: 2B                                                                                    0.2s
 => [1/2] FROM docker.io/library/almalinux:9-minimal@sha256:5ad6bf379aa6b895b0361314f640d6318e9582a0c90810d58c804  0.6s
 => => resolve docker.io/library/almalinux:9-minimal@sha256:5ad6bf379aa6b895b0361314f640d6318e9582a0c90810d58c804  0.6s
 => CACHED [2/2] RUN microdnf install -y nmap-ncat && microdnf clean all                                           0.0s
 => exporting to image                                                                                             3.2s
 => => exporting layers                                                                                            0.1s
 => => exporting manifest sha256:7903969f6db1da95605caa5a62af73707f0cbbf325e0e3da33359e9430667e04                  0.1s
 => => exporting config sha256:c978115671dc958b41a86c9773eede26225e05499ac6c0d364832e95c3c90bf3                    0.0s
 => => exporting attestation manifest sha256:d318d086f42615145afd9b192aee470bbc464acc8c723f070bdf5289219c0448      0.9s
 => => exporting manifest list sha256:852848aca407c57e295016016f10bb40c046c8e4cdd56f617911651cfc8e86c7             0.5s
 => => naming to docker.io/library/daytime:latest                                                                  0.3s
 => => unpacking to docker.io/library/daytime:latest                                                               0.2s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/7mtm150b58gwwhcoorpa7y5cz


PS C:\> # Docker イメージの存在を確認する (イメージが実行中の場合は EXTRA の列に  U  が表示される) PS C:\> docker images daytime i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA daytime:latest 852848aca407 149MB 38.6MB U PS C:\> exit


3-2. 動作確認をする。

3-2-1. コンテナを起動する。
ここでは、自ホストの 1300 番ポートを経由してコンテナにアクセスする。
また、テストのためフォアグラウンドで実行する。(-d を付けない)

− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # コンテナを起動する
PS C:\> # 確認 (下記 3-2-2) ができたら  で停止させる。
PS C:\> docker run -p 1300:130 --rm --init --name daytime-0 daytime 

PS C:\> exit 

-p : ホストポートとコンテナポート*2を指定する。
--rm : 実行後にコンテナのワークを削除する。(一時ファイルやログ)
--init : 終了シグナルの受け口を設けて正常終了を可能にする。(Ctrl + C を使用する場合は必須)
--name : 実行インスタンスの名称を指定する。(ひとつのイメージから複数のインスタンスを実行可能)
*2一般にターゲットポートと呼ばれる。

3-2-2. 別のターミナルから確認する。(同じコンピュータ)
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # 現在時刻を問い合わせる
PS C:\> curl.exe --max-time 0.1 telnet://127.0.0.1:1300 
Tue Mar  3 12:50:53 UTC 2026    ← 応答が得られた (現在時刻)


PS C:\> # コンテナを停止させる場合はこちら PS C:\> docker stop daytime-0 daytime-0 PS C:\> exit


3-3. Docker イメージの削除

− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # Docker イメージの存在を確認する
PS C:\> docker images daytime 
                                                           i Info →   U  In Use
IMAGE            ID             DISK USAGE   CONTENT SIZE   EXTRA
daytime:latest   852848aca407        149MB         38.6MB    U 


PS C:\> # Docker イメージを削除する PS C:\> docker image rm daytime Untagged: daytime:latest Deleted: sha256:852848aca407c57e295016016f10bb40c046c8e4cdd56f617911651cfc8e86c7
PS C:\> # Docker イメージの削除を確認する PS C:\> docker images daytime i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA --- daytime:latest は表示されない ---
PS C:\> # ワークを削除する。 PS C:\> # 既に終了したコンテナのワークをすべて削除する。(一時ファイルやログ) PS C:\> docker container prune WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Deleted Containers: cb0a8215a0a7d916e3a2bc1b753a3dd50fe460fb050ceb235efa0efc7707d344 bc4c49cb10c49e20984f9eb7d3edcb1f03d6b88153d5f7f37b78315de16c7ee1 Total reclaimed space: 0B PS C:\> exit


4. じゃんけんシステムの作成

3 つのじゃんけんサーバを動作させ、それぞれの勝敗をカウントする。
じゃんけんサーバはグー・チョキ・パーを返すだけとし、進行役コンテナが勝敗を取りまとめる。
それらを相互接続するために、ユーザ定義ブリッジネットワークを作成する。

プログラムは Python を使用し、Flask を使ったじゃんけんサーバ 1 つ*3と、MC クライアント*4を作成する。
*3 1 つのイメージを、名前を変えて 3 つ起動する。
*4 MC: 司会進行役のこと。イベントを進行させたり、盛り上げたりする。

4-1. じゃんけんサーバを作成する。
4-1-1. プレイヤーのプログラムを作成する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # イメージ作成用フォルダを作成する
PS C:\> mkdir -Force .\janken\ 


PS C:\> # プレイヤープログラムとして "player.py" を作成する PS C:\> @" #!/usr/bin/env python3 from flask import Flask, jsonify import os, random MY_NAME = os.getenv('MY_NAME', 'unknown') app = Flask(__name__) @app.route('/hand') def get_hand(): # ランダムに手を返す hand = random.choice([ 'R', # Rock グー 'P', # Paper パー 'S', # Scissors チョキ ]) return jsonify({"name": MY_NAME, "hand": hand}) if __name__ == '__main__': app.run(host='0.0.0.0', port=8080) "@ | Out-File -Encoding utf8 .\janken\player.py
PS C:\> # Dockerfile として "player" を作成する PS C:\> @" # 材料(OS)の指定 FROM almalinux:9 # 作業ディレクトリの指定 WORKDIR /app # 道具のインストール(ビルド時にネットワークが必要) RUN dnf install -y python3 python3-pip RUN pip3 install flask # リッスンポート (省略可。Docker Desktop では必須) EXPOSE 8080 # プログラムをコンテナの中へ入れる COPY player.py /app/player.py # 起動時に実行するコマンド (AUTOEXEC) ENTRYPOINT ["python3"] CMD ["player.py"] "@ | Out-File -Encoding utf8 .\janken\player
PS C:\> # プレイヤーをビルドする PS C:\> docker build -t janken-player -f .\janken\player .\janken\ PS C:\> exit
4-1-2. プレイヤーの動作を確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # プレイヤーをバックグラウンドとして起動する (コンテナ名: jp1)
PS C:\> # -d: バックグラウンドオプション
PS C:\> docker run -d --rm -p 8080:8080 --name jp1 -e MY_NAME=jp1 janken-player 
5af15fa686ef575c0685f90e501e0e68de5b2e857c408845fe58518d888567f2  ← コンテナID(毎回異なる)


PS C:\> # プレイヤーを呼び出す (複数回) PS C:\> curl.exe localhost:8080/hand ; curl.exe localhost:8080/hand {"hand":"R","name":"jp1"} ← グーを返した {"hand":"S","name":"jp1"} ← チョキを返した
PS C:\> # プレイヤーを停止させる (コンテナ名: jp1) PS C:\> docker stop jp1 PS C:\> exit

4-2. MC クライアントを作成する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # クライアントプログラムとして "mc.py" を作成する
PS C:\> @"
#!/usr/bin/env python3

import requests, time

time.sleep(3) # プレイヤーの起動を待つ

nodes = [
  'http://jp1:8080/hand',
  'http://jp2:8080/hand',
  'http://jp3:8080/hand',
]

results = {'jp1': 0, 'jp2': 0, 'jp3': 0}

def judge(h_a, h_b, h_c):
    hands = set([h_a, h_b, h_c])

    # 3種類出た、または1種類だけなら「あいこ」
    if len(hands) == 3: return []
    if len(hands) == 1: return []
    
    # 勝敗が決まる場合(2種類のみ存在)
    win_map = {
      'R': 'S',   # グー : チョキ
      'S': 'P',   # チョキ : パー
      'P': 'R',   # パー : グー
    }

    # どの手が勝っているか特定
    h1, h2 = list(hands)
    winner_hand = h1 if win_map[h1] == h2 else h2
    
    # 勝った手を出した人をリストで返す
    winners = []
    if h_a == winner_hand: winners.append('jp1')
    if h_b == winner_hand: winners.append('jp2')
    if h_c == winner_hand: winners.append('jp3')

    return winners

for i in range(10):

    print(f'Round {i+1: >2}:', end='')
    try:
        # 3人から手を取得
        h_a = requests.get(nodes[0]).json()['hand']
        h_b = requests.get(nodes[1]).json()['hand']
        h_c = requests.get(nodes[2]).json()['hand']
        
        winners = judge(h_a, h_b, h_c)
        for w in winners:
            results[w] += 1
            
        print(f'jp1:{h_a}, jp2:{h_b}, jp3:{h_c} -> 勝ち: {winners}')
    except Exception as e:
        print(f'Error: {e}')

print('-----')
print(f'結果: {results}')
"@ | Out-File -Encoding utf8 .\janken\mc.py 


PS C:\> # MC クライアントの Dockerfile として "mc" を作成する PS C:\> @" # 材料 (OS) の指定 FROM almalinux:9 # 作業ディレクトリを設定 WORKDIR /app # Python と HTTPリクエスト用のライブラリをインストール # (ビルド時にネットワークが必要) RUN dnf install -y python3 python3-pip && \ pip3 install requests # MC のプログラムをコンテナ内にコピー COPY mc.py /app/mc.py # 起動時に実行するコマンド (AUTOEXEC) ENTRYPOINT ["python3", "mc.py"] "@ | Out-File -Encoding utf8 .\janken\mc
PS C:\> # MC クライアントをビルドする PS C:\> docker build -t janken-mc -f .\janken\mc .\janken\ PS C:\> exit

4-3. 動作を確認する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # ユーザ定義ブリッジネットワークを janken-net の名称で作成する
PS C:\> docker network create janken-net 
3e13c3a3f0eeba0cbc21d5cf7b61528749b67c2b7cbcf54e1350c6225d767b75  ← インスタンスID(毎回異なる)


PS C:\> # じゃんけんプレイヤーを 3 つ起動する。(janken-net に接続) PS C:\> docker run -d --rm --init --name jp1 --network janken-net -e MY_NAME=jp1 janken-player PS C:\> docker run -d --rm --init --name jp2 --network janken-net -e MY_NAME=jp2 janken-player PS C:\> docker run -d --rm --init --name jp3 --network janken-net -e MY_NAME=jp3 janken-player
PS C:\> # MC クライアントを実行する。(janken-net に接続) PS C:\> docker run --rm --init --name jmc --network janken-net janken-mc Round 1:jp1:S, jp2:S, jp3:S -> 勝ち: [] Round 2:jp1:P, jp2:S, jp3:S -> 勝ち: ['jp2', 'jp3'] Round 3:jp1:R, jp2:S, jp3:R -> 勝ち: ['jp1', 'jp3'] Round 4:jp1:P, jp2:R, jp3:P -> 勝ち: ['jp1', 'jp3'] Round 5:jp1:R, jp2:P, jp3:S -> 勝ち: [] Round 6:jp1:S, jp2:R, jp3:R -> 勝ち: ['jp2', 'jp3'] Round 7:jp1:R, jp2:P, jp3:P -> 勝ち: ['jp2', 'jp3'] Round 8:jp1:P, jp2:S, jp3:R -> 勝ち: [] Round 9:jp1:R, jp2:R, jp3:R -> 勝ち: [] Round 10:jp1:P, jp2:R, jp3:S -> 勝ち: [] ----- 結果: {'jp1': 2, 'jp2': 3, 'jp3': 5}
PS C:\> # じゃんけんプレイヤーを 3 つ停止させる PS C:\> docker stop jp1 jp2 jp3
PS C:\> # ユーザ定義ブリッジネットワーク janken-net を削除する PS C:\> docker network rm janken-net PS C:\> exit


5. Docker イメージの受け渡し

Docker イメージはローカルリポジトリを基本として動作するため、他の環境へ移すにはセーブ・ロードの作業が必要になる。
tar 形式だが、セーブ後の圧縮は不要。

5-1. イメージをまとめてセーブする。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # イメージをまとめてセーブする
PS C:\> docker save janken-player janken-mc -o janken.tar 

PS C:\> # 内容を確認する
PS C:\> tar -xOf janken.tar manifest.json | ConvertFrom-Json | ForEach-Object { $_.RepoTags }  
janken-player:latest
janken-mc:latest

PS C:\> exit 

5-2. イメージをまとめてロードする。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows        

PS C:\> # イメージをまとめてロードする
PS C:\> docker load -i janken.tar 
Loaded image: janken-player:latest
Loaded image: janken-mc:latest

PS C:\> exit 


6. Compose の利用

Compose 機能を使用すると、上記 4-3 をまとめて実行できるようになる。

6-1. YAML で依存関係を記述する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows        

PS C:\> # YAML で依存関係を記述する
PS C:\> @"
services:
  jp1:      # プレイヤー 1
    image: janken-player
    attach: false   # -d の指定
    init: true      # --init の指定
    environment:
      MY_NAME: jp1
    networks:
      - janken-net

  jp2:      # プレイヤー 2
    image: janken-player
    attach: false
    init: true
    environment:
      MY_NAME: jp2
    networks:
      - janken-net

  jp3:      # プレイヤー 3
    image: janken-player
    attach: false
    init: true
    environment:
      MY_NAME: jp3
    networks:
      - janken-net

  jmc:      # MCクライアント
    image: janken-mc
    attach: true
    depends_on:
      - jp1
      - jp2
      - jp3
    networks:
      - janken-net

networks:
  janken-net:
"@ | Out-File -Encoding utf8 .\janken\janken.yml 

PS C:\> exit 

6-2 Compose で実行する。
Windows の仕様のせいで WSL2 とのストリーム処理が同期しない。
これを回避するため $null |  で強制的にバッファを開放している。
プロジェクトすべてをデタッチ起動にして logs を取得すれば、この必要はない。
(docker compose … ls をしないなら up に --abort-on-container-exit を付加しても良い)

− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows        

PS C:\> # Compose で実行する
PS C:\> # Compose はプロジェクト単位で動作するため -p でプロジェクト名を指定する
PS C:\> # [+] up 5/5 等のステータス表示が不要の場合は 2> $nul で標準エラーを捨てる
PS C:\> $null | docker compose -f ./janken/janken.yml -p janken-prj up 
[+] up 5/5
  Network janken-prj_janken-net Created                   0.1
  Container janken-prj-jp1-1    Started                   0.5
  Container janken-prj-jp2-1    Started                   0.5
  Container janken-prj-jp3-1    Started                   0.5
  Container janken-prj-jmc-1    Started                   0.7
Attaching to jmc-1
jmc-1  | Round  1:jp1:R, jp2:P, jp3:R -> 勝ち: ['jp2']
jmc-1  | Round  2:jp1:P, jp2:S, jp3:P -> 勝ち: ['jp2']
jmc-1  | Round  3:jp1:S, jp2:P, jp3:R -> 勝ち: []
jmc-1  | Round  4:jp1:S, jp2:S, jp3:S -> 勝ち: []
jmc-1  | Round  5:jp1:S, jp2:P, jp3:S -> 勝ち: ['jp1', 'jp3']
jmc-1  | Round  6:jp1:S, jp2:R, jp3:R -> 勝ち: ['jp2', 'jp3']
jmc-1  | Round  7:jp1:R, jp2:S, jp3:P -> 勝ち: []
jmc-1  | Round  8:jp1:R, jp2:P, jp3:P -> 勝ち: ['jp2', 'jp3']
jmc-1  | Round  9:jp1:R, jp2:P, jp3:P -> 勝ち: ['jp2', 'jp3']
jmc-1  | Round 10:jp1:P, jp2:S, jp3:R -> 勝ち: []
jmc-1  | -----
jmc-1  | 結果: {'jp1': 1, 'jp2': 5, 'jp3': 4}
jmc-1 exited with code 0


PS C:\> # Compose の状態を見る PS C:\> docker compose -p janken-prj ls NAME STATUS CONFIG FILES janken-prj running(3) C:\Users\who\janken\janken.yml
PS C:\> # Compose で停止する PS C:\> $null | docker compose -p janken-prj down [+] down 5/5 Container janken-prj-jmc-1 Removed 0.0s Container janken-prj-jp1-1 Removed 10.2 Container janken-prj-jp2-1 Removed 10.2 Container janken-prj-jp3-1 Removed 10.2 Network janken-prj_janken-net Removed 0.12 PS C:\> # docker compose down が完全に終了するまで待つ PS C:\> Start-Sleep -Seconds 5 PS C:\> exit
Compose は複数起動を許容するため jmc → jmc-1 となる。
これを抑止するには YAML で container_name: jmc を記述して固定化する。(スケーリングを阻害するので、ふつうはやらない)