はじめに
「Docker Desktop for Windowsをインストールしたはいいけど、結局よくわかっていないまま使っている」という人は意外と多いです。docker runやdocker-compose upは打てるけど、WSL2って何なのか、なぜたまにファイル変更が反映されないのか、なぜチームメンバーによって動いたり動かなかったりするのか——そのあたりの「なぜ」を説明できる人は少ない印象があります。
この記事では、Docker Desktop for Windowsを「猿でもわかる」レベルの基礎知識から、実務で「あ、これ知らないと詰む」というレベルの知識まで、地に足の着いた粒度でまとめます。逆に言うと、公式ドキュメントの丸写しや、めったに使わない機能の網羅は避け、実際に手を動かすときに役立つ情報に絞っています。
対象読者は以下のような人です。
- Dockerを触り始めたばかりのWindowsユーザー
- なんとなく使えているが、WSL2やバックエンドの違いを説明できない人
- チーム開発でDocker Desktopを使っていて、環境差異のトラブルに悩んだことがある人
- Docker Desktopの有料化・ライセンス問題を把握しておきたい人
なお、本記事の内容は執筆時点(2026年)の情報をベースにしています。Dockerの仕様やDocker Desktopのライセンス体系は変わることがあるので、細かい数値や料金は必ず公式サイトで最新情報を確認してください。
目次
- Dockerとは何か(超基礎)
- Docker Desktop for Windowsとは何者か
- インストール前に理解しておくべきWSL2の話
- インストール手順
- 初回起動・基本設定
- WSL2バックエンドとHyper-Vバックエンドの違い
- 基本コマンドを体で覚える
- Dockerfileの書き方(実務目線)
- Docker Composeで複数コンテナを扱う
- ボリュームとバインドマウント、Windows特有の落とし穴
- ネットワークの基礎と実務での注意点
- リソース設定(メモリ・CPU・ディスク)
- パフォーマンスチューニングの勘所
- よくあるトラブルと対処法
- セキュリティの基礎知識
- ライセンスと料金の話(見落としがち)
- CI/CDとの付き合い方(さわり)
- チーム開発で環境差異を減らすためのプラクティス
- まとめ
- 参考リンク
1. Dockerとは何か(超基礎)
1.1 一言でいうと
Dockerは「アプリケーションとその実行環境を丸ごとパッケージ化して、どこでも同じように動かす」ための技術です。
たとえば「自分のPCでは動くのに、本番サーバーでは動かない」という現象、経験ありませんか。原因はだいたい、OSのバージョン差、ライブラリのバージョン差、環境変数の設定漏れなど、「環境の違い」です。Dockerはこの環境ごとアプリを封じ込めることで、この問題を解決しようとしています。
1.2 コンテナと仮想マシンの違い
よく「仮想マシン(VM)みたいなもの?」と聞かれますが、厳密には違います。VMはハードウェアごとエミュレートしゲストOS全体を載せるため重く起動も遅い一方、コンテナはホストOSのカーネルを共有しつつプロセスやファイルシステムだけを隔離するため軽量・高速です。VMが「家をまるごと1軒建てる」イメージなら、コンテナは「同じマンションの中で部屋を区切って住む」イメージに近いです。
ただしこれは本来Linuxカーネルの機能(namespaceやcgroups)を使った話であり、Windowsには同じ仕組みがそのまま存在しません。ここが後述するWSL2の話につながってきます。
1.3 イメージとコンテナの関係
Dockerを理解するうえで最初につまずきやすいのが「イメージ」と「コンテナ」の違いです。
イメージ(Image)はアプリと実行環境の「設計図」であり読み取り専用のスナップショット、コンテナ(Container)はそのイメージを実際に実行した「インスタンス」です。クラスとインスタンスの関係に近く、同じイメージから何個でもコンテナを起動でき、それぞれ独立して動きます。
1.4 Docker Hubとレジストリ
イメージはローカルで自作することもできますが、多くの場合は既に誰かが作った公式イメージ(nginx、mysql、nodeなど)を「Docker Hub」というレジストリから取得(pull)して使います。会社によってはセキュリティ上の理由から、社内のプライベートレジストリ(Amazon ECRやGitHub Container Registryなど)を使うこともあります。
2. Docker Desktop for Windowsとは何者か
2.1 「Docker」と「Docker Desktop」は別物
「Docker」というエンジン本体(Docker Engine)は、もともとLinux専用に作られたソフトウェアで、Windows上でそのまま動かすことはできません。そこでWindowsやMac向けに、以下をひとまとめにして提供しているのがDocker Desktopです。
- Docker Engine(実際にはLinux VM/WSL2の中で動いている)
- Docker CLI(コマンドラインツール)
- Docker Compose
- GUI管理画面(コンテナ一覧やログの確認、設定変更など)
- Kubernetes(オプションで有効化可能)
- ボリューム管理、ネットワーク管理などの周辺機能
つまりDocker Desktopは「WindowsでLinuxのDockerを違和感なく使うための箱」だと理解しておくとよいです。
2.2 なぜWindowsだと一枚噛ませる必要があるのか
DockerコンテナはLinuxカーネルの機能に依存しており、Windowsのカーネルとは互換性がありません。そのため内部的に「軽量なLinux環境」を用意してその中でDocker Engineを動かし、Windows側はCLIやGUIで橋渡しする、という構造になっています。この軽量なLinux環境を提供する技術が、次章で説明するWSL2です。
3. インストール前に理解しておくべきWSL2の話
3.1 WSL2とは
WSL(Windows Subsystem for Linux)は、Windows上でLinux環境を動かすための仕組みです。バージョン1と2がありますが、現在のDocker DesktopはWSL2を前提にしています。
WSL1はWindowsカーネルの上でLinuxのシステムコールを「翻訳」して動かす方式でしたが、WSL2は実体として軽量な仮想マシンの中で本物のLinuxカーネルを動かす方式です。この違いにより、WSL2はファイルI/Oやネットワーク周りの互換性・パフォーマンスが大幅に向上しています。
3.2 なぜDocker DesktopはWSL2を使いたがるのか
WSL2バックエンドを使うと、以下のようなメリットがあります。
- 起動が速い
- メモリ・CPUの使用効率が良い(VMのリソースを動的に調整できる)
- Linux用に書かれたツールやスクリプトとの親和性が高い
- WSL2上のLinuxディストリビューション(Ubuntuなど)内のファイルシステムに対して、ネイティブに近い速度でアクセスできる
逆にいうと、後述する「Windows側のファイルをバインドマウントして使う」ケースでは、WSL2を使っていてもファイルI/Oが遅くなることがあります。ここは要注意ポイントとして13章で詳しく触れます。
3.3 有効化しておくべきWindowsの機能
インストール前に、以下がWindows側で有効になっている必要があります。
- 仮想化支援機能(Intel VT-x / AMD-V):BIOS/UEFIで有効にする。多くのPCはデフォルトで有効。
- Windowsの機能「Windows Subsystem for Linux」
- Windowsの機能「仮想マシン プラットフォーム」
これらはPowerShellで以下のように有効化できます(管理者権限で実行)。
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
有効化後は再起動が必要です。また、WSLのバージョン自体も更新しておくとトラブルが減ります。
wsl --update
wsl --set-default-version 2
3.4 会社PCで詰まりがちなポイント
企業PCでは、グループポリシーによる仮想化機能の制限、Hyper-Vと競合する他の仮想化ソフト(古いVirtualBoxなど)、管理者権限不足でWindowsの機能を有効化できない、といった理由でハマりがちです。導入前に情シス部門へ「仮想化支援機能の有効化」「WSL2の利用許可」を確認しておくとトラブルを避けられます。
4. インストール手順
4.1 ダウンロードとインストール
- Docker公式サイトから「Docker Desktop for Windows」のインストーラーをダウンロードする
- インストーラーを実行し、「Use WSL 2 instead of Hyper-V」にチェックが入っていることを確認する(デフォルトでオンのことが多い)
- インストール完了後、PCを再起動する
- 再起動後、Docker Desktopを起動する
4.2 初回起動時に聞かれること
- 利用規約への同意
- Docker ID(アカウント)でのサインイン(任意、ただしDocker Hubからのpullに一部制限がかかる場合があるためサインイン推奨)
- 個人利用か商用利用かの選択(後述のライセンスの話に関連)
4.3 インストールできたかの確認
PowerShellまたはコマンドプロンプトで以下を実行し、バージョンが表示されればOKです。
docker --version
docker compose version
さらに、実際にコンテナが動くかどうかを確認するには、公式が用意している動作確認用イメージを使うのが定番です。
docker run hello-world
「Hello from Docker!」というメッセージが表示されれば、インストールは成功です。
5. 初回起動・基本設定
5.1 Settings画面で最初に見るべき場所
Docker Desktopの歯車アイコン(Settings)から、以下の項目は最初に確認しておくとよいです。
- General:WSL2バックエンドの利用有無、起動時の自動起動設定
- Resources > WSL Integration:どのWSLディストリビューションにDocker統合を有効にするか
- Resources > Advanced:メモリ・CPU・ディスクの割り当て(Hyper-Vバックエンド利用時のみ調整可能。WSL2バックエンドの場合はWSL側の設定ファイルで調整)
5.2 WSL Integrationの落とし穴
複数のLinuxディストリビューション(Ubuntu、Debianなど)をWSLに入れている場合、Docker DesktopのWSL Integrationで該当のディストリビューションを有効化しないと、そのディストリビューション内のターミナルからdockerコマンドが使えません。「WSLのUbuntuからdockerコマンドが見つからない」という質問はほぼ100%これが原因です。
設定場所:Settings → Resources → WSL Integration → 該当ディストリビューションのトグルをON
5.3 ターミナルはどこから使うべきか
コマンドを打つ場所は、PowerShell/コマンドプロンプト(Windows側)、WSL2内のLinuxシェル(bashなど)、両方を切り替えられるWindows Terminalが選択肢になります。開発対象がLinux向けのアプリ(Webアプリのバックエンドなど)であれば、WSL2内のシェルから作業することを強く推奨します。理由は10章で説明するファイルI/Oのパフォーマンス問題に直結するためです。
6. WSL2バックエンドとHyper-Vバックエンドの違い
6.1 2つのバックエンド
Docker Desktop for Windowsには、内部でDockerを動かす方式として2種類あります。
- WSL2バックエンド(現在の標準・推奨)
- Hyper-Vバックエンド(旧来の方式)
6.2 比較表
| 項目 | WSL2バックエンド | Hyper-Vバックエンド |
|---|---|---|
| 起動速度 | 速い | 遅め |
| リソース使用効率 | 動的に調整、軽量 | VMに固定的にリソース確保 |
| Windows Home対応 | 対応 | 非対応(Pro/Enterprise/Education限定) |
| Linuxツールとの親和性 | 高い | 普通 |
| 必要なWindows機能 | WSL2 | Hyper-V |
6.3 実務上の結論
現在は基本的にWSL2バックエンドを使えばよく、意図的にHyper-Vを選ぶ理由はほとんどありません。社内ポリシーでWSL2が禁止されている、古い運用手順がHyper-V前提になっている、といった事情がなければ、新規セットアップは素直にWSL2バックエンドで問題ありません。
7. 基本コマンドを体で覚える
ここからは実際に手を動かすコマンドです。最初はすべて覚えなくてよいので、「よく使うもの」に絞って体に染み込ませるのが実務的です。
7.1 イメージ関連
# イメージを取得する
docker pull nginx
# ローカルにあるイメージ一覧を見る
docker images
# 使っていないイメージをまとめて削除する
docker image prune
7.2 コンテナ関連
# コンテナを起動する(-dはバックグラウンド実行、-pはポート指定)
docker run -d -p 8080:80 --name my-nginx nginx
# 動いているコンテナ一覧
docker ps
# 停止しているものも含めた全コンテナ一覧
docker ps -a
# コンテナを停止する
docker stop my-nginx
# コンテナを削除する
docker rm my-nginx
# コンテナの中に入ってシェルを操作する
docker exec -it my-nginx bash
# コンテナのログを見る
docker logs -f my-nginx
7.3 実務でよく忘れがちなオプション
-
--rm:コンテナ終了時に自動で削除する(使い捨てで試す時に便利) -
-e:環境変数を渡す(例:-e NODE_ENV=production) -
-v:ボリューム・バインドマウントを指定する(10章で詳述) -
--name:コンテナに名前をつける(つけないとランダムな名前になり管理しづらい)
docker run --rm -it -e NODE_ENV=development -v ${PWD}:/app -w /app node:20 bash
7.4 掃除コマンド(実務で頻出)
Docker Desktopを使っていると、意外とディスク容量を食います。定期的に掃除するコマンドを覚えておくと安心です。
# 停止中コンテナ、未使用イメージ、未使用ネットワークなどをまとめて削除
docker system prune
# ボリュームも含めて削除(データが消えるので注意)
docker system prune --volumes
--volumesをつけると永続化データも消えるため、実務では慎重に扱ってください。
8. Dockerfileの書き方(実務目線)
8.1 最小構成
Dockerfileはイメージの設計図をコードとして書いたものです。Node.jsアプリを例にすると、最低限はこのようになります。
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
8.2 レイヤーキャッシュを意識する
Dockerfileは上から順に「レイヤー」として実行され、変更がない行はキャッシュが再利用されます。上の例でpackage*.jsonだけ先にコピーしてnpm installしてから、残りのソースコードをコピーしているのは、ソースコードを変更しただけではnpm installが再実行されないようにするためです。この順番を意識するだけでビルド時間が大幅に変わります。
8.3 マルチステージビルド
本番用イメージのサイズを小さくするために、ビルド用と実行用でステージを分けるのが実務では定番です。
# ビルドステージ
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 実行ステージ
FROM node:20-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
ビルドに必要なツール類(TypeScriptコンパイラなど)は最終イメージに含めず、実行に必要なものだけを持っていくことで、イメージサイズもセキュリティ面のリスクも小さくできます。
8.4 .dockerignoreを忘れずに
node_modulesや.gitなどをビルドコンテキストに含めてしまうと、ビルドが遅くなったり、意図しないファイルがイメージに混入したりします。プロジェクトルートに.dockerignoreを置くのは必須級の習慣です。
node_modules
.git
.env
*.log
dist
8.5 イメージタグの付け方を雑にしない
latestタグだけに頼った運用は実務では事故のもとです。「いつのビルドかわからない」「ロールバックできない」状態になりがちなので、Gitのコミットハッシュやセマンティックバージョンをタグに含める運用をおすすめします。
docker build -t myapp:1.2.0 -t myapp:latest .
9. Docker Composeで複数コンテナを扱う
9.1 なぜComposeが必要か
実務のアプリケーションは、Webサーバー・アプリケーション・DB・キャッシュなど複数のコンテナが連携して動くのが普通です。それぞれを個別にdocker runで起動・管理するのは非効率なので、複数コンテナの構成をYAMLファイルにまとめて一括管理する仕組みがDocker Composeです。
9.2 基本的なcompose.yml
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=development
volumes:
- .:/app
- /app/node_modules
depends_on:
- db
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=example
volumes:
- db-data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
db-data:
9.3 よく使うコマンド
# 起動(ビルドが必要な場合は自動でビルドされる)
docker compose up
# バックグラウンドで起動
docker compose up -d
# 停止と削除
docker compose down
# ボリュームも含めて削除
docker compose down -v
# ログを見る
docker compose logs -f web
# 特定サービスだけ再ビルド
docker compose build web
9.4 depends_onは「起動順序」であって「準備完了待ち」ではない
実務で必ずハマるポイントです。depends_onはコンテナの起動順序を制御するだけで、DB内でPostgreSQLが実際に接続を受け付けられる状態になるまで待ってくれません。アプリ側でリトライ処理を入れるか、healthcheckとcondition: service_healthyを組み合わせます。
services:
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
web:
build: .
depends_on:
db:
condition: service_healthy
9.5 環境変数の管理は.envファイルで
compose.ymlに直接パスワードを書き込むのは避け、.envファイルに分離するのが一般的です。Composeは同じディレクトリの.envを自動で読み込みます。
# .env
POSTGRES_PASSWORD=supersecret
services:
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
当然、.envは.gitignoreに入れてリポジトリにコミットしないようにします。
10. ボリュームとバインドマウント、Windows特有の落とし穴
10.1 3種類の永続化方法
- 名前付きボリューム(Volume):Dockerが管理する領域。DBのデータなど、永続化したいがホスト側で直接編集しない用途向き。
- バインドマウント(Bind Mount):ホスト側の特定フォルダをそのままコンテナにマウントする。ソースコードの編集をリアルタイムに反映したい開発時に使う。
- tmpfsマウント:メモリ上の一時領域。永続化不要な一時データ向き(Windows版では利用制限あり)。
10.2 Windows特有の「遅い」問題
これが実務で最もハマりやすいポイントです。Windows側のファイルシステム(Cドライブなど)をバインドマウントすると、WSL2バックエンドであってもファイルI/Oが顕著に遅くなることがあります。
原因は、WSL2の中のLinux環境から見て、Windows側のファイルシステム(/mnt/c/...配下)へのアクセスは、WSL2内のネイティブなLinuxファイルシステムへのアクセスに比べてオーバーヘッドが大きいためです。
対処法としては、次のいずれかが定番です。
-
プロジェクトのソースコード自体をWSL2側(Linuxファイルシステム)に置く(
\\wsl$\Ubuntu\home\ユーザー名\projectsのような場所、あるいはWSL内で~/projectsとして作業する) - Windows Terminalやエディタ(VS Codeの「Remote - WSL」拡張機能など)もWSL2側から開くようにする
- どうしてもWindows側にファイルを置く必要がある場合は、パフォーマンス低下を許容するか、開発用途を限定する
特にVS Codeを使っている場合、「Remote - WSL」拡張機能を入れて、WSL2内のプロジェクトフォルダを直接開く運用にすると、体感速度が大きく改善します。これはWindowsでのDocker開発における最重要ノウハウの一つと言ってよいです。
10.3 パスの書き方の違いに注意
Windows側のパス(C:\Users\username\project)と、WSL2内から見たパス(/mnt/c/Users/username/project)、コンテナ内から見たパス(/appなど)の3種類が混在するため、混乱しがちです。基本方針として「compose.ymlやDockerfileはWSL2内で作業し、パスはLinux形式で書く」と決めておくと迷いが減ります。
10.4 改行コード(CRLF/LF)問題
Windowsで作成したシェルスクリプト(entrypoint.shなど)を含むイメージをビルドすると、改行コードがCRLFのままになっていて、コンテナ内(Linux)で実行時に「bad interpreter」のようなエラーが出ることがあります。Gitの設定で改行コードをLFに統一する(.gitattributesで* text=auto eol=lfを指定するなど)か、エディタの改行コード設定をLFに固定しておくことをおすすめします。
11. ネットワークの基礎と実務での注意点
11.1 デフォルトのネットワーク
Docker Composeでサービスを起動すると自動的に専用のネットワークが作られ、同じネットワーク内のコンテナ同士はサービス名で名前解決できます。先ほどの例でいえば、webコンテナからdbコンテナへは、IPアドレスではなくサービス名dbでアクセスできます。
# webコンテナ内のアプリの接続文字列イメージ
postgres://user:pass@db:5432/mydb
11.2 ポートマッピングの考え方
ports: - "3000:3000"のような記法は、ホスト側ポート:コンテナ側ポートの順です。ホスト側のポートを変えたい場合は左側を変更します。
ports:
- "8080:3000" # ホストの8080番でアクセスすると、コンテナ内の3000番につながる
11.3 localhostで繋がらない問題
Windows上でDocker Desktopを使っている場合、コンテナで公開したポートは基本的にWindows側からもlocalhostでアクセスできるようになっています(WSL2バックエンドのおかげで、この点はかなり改善されています)。もし繋がらない場合は、以下を確認してください。
- コンテナが実際に起動しているか(
docker ps) - ポートマッピングが正しいか
- コンテナ内のアプリが
127.0.0.1ではなく0.0.0.0でLISTENしているか(アプリが127.0.0.1だけにバインドしていると、コンテナ外からアクセスできません)
この「0.0.0.0でバインドしていない」問題は、Node.jsやPythonのWebフレームワークでデフォルト設定のまま動かしたときによく起きるので、覚えておくと役立ちます。
12. リソース設定(メモリ・CPU・ディスク)
12.1 WSL2のリソース設定は.wslconfigで行う
WSL2バックエンドを使っている場合、Docker Desktopの画面上ではメモリ・CPUの割り当てを直接いじれないことがあります(バージョンによって挙動が異なります)。その場合は、Windowsのユーザーフォルダ直下に.wslconfigというファイルを作成して設定します。
# C:\Users\ユーザー名\.wslconfig
[wsl2]
memory=8GB
processors=4
swap=2GB
設定変更後は以下を実行してWSLを再起動する必要があります。
wsl --shutdown
その後Docker Desktopを起動し直せば設定が反映されます。
12.2 メモリの割り当てすぎ・少なすぎ問題
割り当てが少なすぎるとDBコンテナなどが頻繁に落ちたりビルドが失敗したりし、多すぎるとWindows本体が重くなります。実務では「PCの物理メモリの半分程度まで」を目安に、開発内容に応じて調整するのが現実的です。
12.3 ディスク容量の圧迫
Docker Desktopは仮想ディスク(WSL2の場合はext4.vhdxというファイル)にイメージやボリュームのデータを蓄積していきます。これは自動的には縮小されないため、使っているうちにCドライブの空き容量をじわじわ圧迫します。
対処法として、7章で紹介したdocker system pruneをこまめに実行することに加え、WSL2の仮想ディスク自体を圧縮するコマンドもあります(Docker Desktopのバージョンによっては、Settings画面から「Disk usage optimization」のような形でGUIから実行できる場合もあります)。
wsl --shutdown
diskpart
# diskpart内で
select vdisk file="C:\Users\ユーザー名\AppData\Local\Docker\wsl\data\ext4.vhdx"
compact vdisk
このあたりは環境によって手順が変わるため、実行前に必ず最新の公式手順を確認してください。
13. パフォーマンスチューニングの勘所
13.1 「遅い」と感じたときのチェックリスト
Docker Desktop for Windowsで「なんか遅い」と感じたら、以下を順番に疑うと原因を特定しやすいです。
- Windows側のファイルをバインドマウントしていないか(10章参照)
- WSL2に割り当てているメモリ・CPUが少なすぎないか(12章参照)
- アンチウイルスソフトがDocker関連のファイルをスキャンして重くなっていないか(除外設定を検討)
- 不要なコンテナ・イメージが溜まってディスクを圧迫していないか
- Composeでビルドキャッシュが効いていない構成になっていないか(8.2節参照)
13.2 アンチウイルスソフトの除外設定
企業PCのセキュリティソフト(Windows Defenderを含む)が、WSL2の仮想ディスクファイルやDockerの動作ディレクトリを逐次スキャンしてしまい、パフォーマンスが著しく低下することがあります。可能なら\\wsl$配下やDocker Desktopのデータディレクトリをスキャン対象から除外することを検討してください(社内ポリシーで変更できない場合は情シスに相談)。
13.3 それでも重い場合の最終手段
Docker Desktopを最新版に上げる、PC自体のメモリとSSD空き容量を見直す、それでも厳しければクラウド上の開発環境やリモートDockerホストへの切り替えを検討する、といった対応になります。
14. よくあるトラブルと対処法
実務でよく遭遇するエラーと、その対処法を一覧にまとめます。
14.1 「WSL 2 installation is incomplete」
WSL2のカーネル更新プログラムが古い、または未インストールの場合に出ます。
wsl --update
を実行し、それでも解決しない場合はMicrosoft公式のWSL2 Linuxカーネル更新プログラムを手動でインストールします。
14.2 「Cannot connect to the Docker daemon」
Docker Desktop自体が起動していない、またはクラッシュしている場合に出ます。タスクトレイのDockerアイコンを確認し、起動していなければ起動する、起動しているのにエラーが出る場合はDocker Desktopを一度完全に再起動(Quitしてから再度起動)します。
14.3 「port is already allocated」
指定したホスト側ポートを、別のプロセス(別のコンテナや、Windows上の別アプリ)がすでに使っている場合に出ます。
# Windows側でポートを使っているプロセスを確認
netstat -ano | findstr :3000
使っていないポート番号に変更するか、該当プロセスを終了させます。
14.4 コンテナ内でファイルを編集しても反映されない
バインドマウントの設定が正しくない、またはWindows側のファイルをマウントしている際のキャッシュ挙動が原因のことがあります。まずはdocker compose configでマウント設定が意図通りか確認し、10章の「ソースコードをWSL2側に置く」対処を検討してください。
14.5 npm installやpip installが異常に遅い
Windows側のファイルをバインドマウントしてnode_modulesや仮想環境をコンテナ内に作っている場合、ファイルI/Oのオーバーヘッドで極端に遅くなることがあります。対処法として、node_modules部分だけを名前付きボリュームに分離するテクニックがあります。
services:
web:
build: .
volumes:
- .:/app
- /app/node_modules # このパスだけコンテナ内の名前付きボリュームを使う
こうすると、ソースコードはホストと同期しつつ、node_modules自体はDockerが管理する高速な領域に隔離されるため、体感速度が改善することが多いです。
14.6 会社のプロキシ環境下でイメージがpullできない
企業ネットワークでプロキシ経由でしかインターネットに出られない場合、Settings → Resources → Proxies からDocker Desktopにプロキシ設定を入れます。あわせて、WSL2内のLinux環境側にも~/.bashrcでのhttp_proxy環境変数などの設定が必要になる場合があります。
14.7 Docker Desktopが起動しない・フリーズする
PCの再起動、Troubleshootメニューからの「Clean / Purge data」(全データが消えるので注意)、それでもダメならアンインストール後にWSL2側のディストリビューションもクリーンな状態に戻して入れ直す、という順で対処します。
15. セキュリティの基礎知識
15.1 rootで動かさない
多くの公式イメージはデフォルトでコンテナ内のプロセスをroot権限で実行しますが、実務では非rootユーザーで実行するのが望ましいです。Dockerfileで明示的にユーザーを指定します。
FROM node:20-slim
RUN useradd -m appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["node", "index.js"]
15.2 イメージの出所を確認する
Docker Hub上には誰でもイメージを公開できるため、出所不明のイメージをそのまま本番で使うのはリスクがあります。可能な限り公式イメージ(Official Images)や信頼できる組織が公開しているイメージを使いましょう。
15.3 シークレットをイメージに焼き込まない
APIキーやパスワードをDockerfile内に直接書いたりCOPYでイメージに含めたりすると、イメージ共有時点で漏洩します。環境変数として実行時に注入するか、DockerのSecrets機能(Swarmモード)、あるいはクラウドのシークレット管理サービスを利用してください。
# NGな例:イメージにパスワードが焼き込まれてしまう
ENV DB_PASSWORD=supersecret
# 実行時に注入する例
services:
web:
environment:
- DB_PASSWORD=${DB_PASSWORD}
15.4 脆弱性スキャンを取り入れる
docker scoutコマンド(Docker Desktopに統合された脆弱性スキャン機能)を使うと、イメージに含まれる既知の脆弱性を確認できます。
docker scout quickview myapp:1.2.0
CI/CDパイプラインに組み込み、脆弱性のあるイメージのデプロイを事前に検知する運用も一般的です。
16. ライセンスと料金の話(見落としがち)
16.1 Docker Desktop自体に商用ライセンスが必要な場合がある
Docker Desktopは無料で使える範囲がありますが、一定規模以上の企業(従業員数や年間売上が一定基準を超える組織)で商用利用する場合、有料サブスクリプション(Docker Pro、Team、Businessなど)の契約が必要になるライセンス体系が導入されています。
個人利用・教育目的・小規模企業(基準は公式サイトで随時更新されるため要確認)については無料枠で利用可能ですが、「うちの会社は対象になるのか」を確認せずに全社導入してしまうと、後からライセンス違反を指摘されるリスクがあります。
導入時には必ず情シス・法務部門と連携し、公式サイトの最新のライセンス条件を確認することを強く推奨します。この記事では料金の具体額には触れませんが、「無料だと思い込んで導入すると危険なケースがある」という点だけは強調しておきます。
16.2 Docker Desktopを使わない選択肢もある
企業によっては、ライセンスコストを避けるためにRancher Desktop、Podman Desktop、あるいはWSL2上へ直接Docker Engineをインストールする構成(Docker Desktopを介さない)を選ぶこともあります。無料で使えるものが多い一方、GUIの使い勝手やWindowsとの統合度はDocker Desktopに軍配が上がることが多いです。組織の方針に応じて選択してください。
17. CI/CDとの付き合い方(さわり)
17.1 ローカルとCI環境の違いを意識する
GitHub ActionsなどのCI環境では通常Linux上でDockerが動いています。ローカル(Windows + Docker Desktop)で動いたからといってCIで同じように動くとは限りません。ファイルパスの大文字小文字の扱い(Windowsは区別しないがLinuxは区別する)、改行コード(10.4節参照)、環境変数の設定漏れが特に差異の出やすいポイントです。
17.2 ローカルでCIに近い状態を再現する
CIの設定ファイル(.github/workflows/*.ymlなど)で使われているdocker buildやdocker runのコマンドを、ローカルでもそのまま実行してみる習慣をつけると、CIで初めてエラーが出て慌てる事態を減らせます。
18. チーム開発で環境差異を減らすためのプラクティス
18.1 「動く環境」をコード化する
Dockerfileやcompose.ymlをリポジトリにコミットし、READMEに手順を書くのではなく「コードとして環境構築を再現できる」状態にしておくことが、チーム開発での事故を減らす基本です。
18.2 バージョンを固定する
FROM node:latestのような書き方は、時間が経つとチームメンバーごとに異なるバージョンのイメージを使ってしまう原因になります。可能な限り具体的なバージョンタグを指定しましょう。
# 避けたい例
FROM node:latest
# 推奨
FROM node:20.11.1-slim
18.3 Windows/Mac混在チームでの注意点
チームにWindowsユーザーとMacユーザーが混在している場合、10章で述べたファイルI/Oの問題に加え、CPUアーキテクチャの違い(Apple SiliconのMacはARM、Windowsは通常x86_64)にも注意が必要です。マルチアーキテクチャ対応のベースイメージを選ぶか、platformを明示的に指定することでトラブルを避けられます。
services:
web:
build: .
platform: linux/amd64
18.4 オンボーディング資料に「詰まりポイント」を書いておく
新しくチームに入った人がセットアップでつまずくポイント(WSL2の有効化、WSL Integrationの設定、.wslconfigの調整など)はほぼ毎回同じです。オンボーディング資料にこの記事のようなチェックリストを用意しておくと、質問対応の工数を大きく減らせます。
19. まとめ
Docker Desktop for Windowsは、単に「dockerコマンドが使えるようになるアプリ」ではなく、内部でWSL2(またはHyper-V)というLinux仮想環境を介して動いている、という構造を理解しておくことが、あらゆるトラブルシューティングの出発点になります。
本記事で扱った内容を振り返ると、実務で本当に効いてくるのは次のようなポイントです。
- WSL2バックエンドを使い、ソースコードはできるだけWSL2側(Linuxファイルシステム)に置く
- WSL Integrationの設定を忘れずに行う
-
depends_onだけでは起動順序しか保証されないので、healthcheckを活用する -
.dockerignoreとマルチステージビルドで、イメージを軽量かつクリーンに保つ - ディスク圧迫、パフォーマンス低下は「Windows側ファイルのバインドマウント」が原因であることが多い
- ライセンス体系は無条件に無料だと思い込まず、組織規模に応じて確認する
最初からすべてを覚える必要はありません。まずは「WSL2の上でDockerが動いている」という全体像を掴み、詰まったときにこの記事のトラブルシューティング章(14章)に立ち返る、という使い方で十分実務に耐えると思います。
20. 参考リンク
- Docker公式ドキュメント:https://docs.docker.com/desktop/install/windows-install/
- Microsoft公式 WSLドキュメント:https://learn.microsoft.com/ja-jp/windows/wsl/
- Docker Compose公式リファレンス:https://docs.docker.com/compose/
(本記事は執筆時点の情報に基づいています。Docker Desktopの仕様・ライセンス体系は変更される可能性があるため、導入や運用の判断をする際は必ず公式の最新情報を確認してください。)