WSL containersで自作イメージをビルドする|Windowsへファイルを保存

  • 公開:2026.10.06
  • 更新:2026.10.06
  • Windows

WSL containersで公開イメージを動かせたら、次は自分のファイルを入れたイメージを作りたくなります。もう一つ気になるのが、コンテナーで作ったファイルをWindowsへ取り出す方法です。終了時にコンテナーを削除する使い方でも、成果物は手元に残しておきたいところです。

ここでは、小さなシェルスクリプトを入れたイメージをビルドし、Windowsの専用フォルダーへ結果を書き出すところまで進めます。Webサーバーを起動せず、ファイルの流れを追える例にしました。

作業用フォルダーを用意する

Windows 11でWSL containersが動く環境と、PowerShellを使います。コマンド例はWSLc 3.0.1で使える構文です。まずはMicrosoftの導入手順に沿ってコンテナーを起動できる状態にし、WSL自体の導入や更新が必要ならWSLのインストールと更新の手順を参照してください。

書き込み可能な作業場所でPowerShellを開き、まだ存在しない専用フォルダーを作ります。同名フォルダーが既にある場合は、新しい名前を選んでください。既存のプロジェクトへサンプルを上書きする必要はありません。

New-Item -ItemType Directory -Path './wslc-file-demo' -ErrorAction Stop | Out-Null
Set-Location './wslc-file-demo'

このフォルダーに、次の2ファイルをテキストエディターで保存します。ファイル名はDockerfileとhello.shです。Dockerfile.txtになっていないか、拡張子も確認してください。

Dockerfileの内容:

FROM alpine:3.22
WORKDIR /app
COPY hello.sh /app/hello.sh
CMD ["/bin/sh", "/app/hello.sh"]

hello.shの内容:

printf 'Hello from WSL containers\n'

hello.shはUTF-8のBOMなし、改行コードはLFで保存すると、Linux側のシェルへそのまま渡せます。この例では/bin/shで読み込むため、実行権限の追加やshebangは不要です。

FROMは土台のAlpine Linux、WORKDIRはコンテナー内の作業場所、COPYはファイルの取り込みを指定します。最後のCMDが、起動時に実行する処理です。ここでファイルをイメージへコピーしても、Windowsの元ファイルと常に同期するわけではありません。

イメージをビルドして実行する

2ファイルを保存したフォルダーで、次のコマンドを実行します。末尾の.がビルドに使うフォルダーで、wslc-file-demo:1は完成したイメージに付ける名前とタグです。初回は公開レジストリからAlpineの取得が必要になるため、通信できる環境で進めてください。

wslc build --progress plain -t wslc-file-demo:1 .
wslc run --rm --network none --cpus 1 --memory 128M wslc-file-demo:1

ビルドが成功したあと、実行したスクリプトは次の文字列を表示します。ビルドに失敗している場合は、先にエラーを解消してからrunを実行してください。

Hello from WSL containers

--rmは終了後にコンテナーを削除する指定です。イメージは残るので、同じコマンドでまた新しいコンテナーを起動できます。--network noneは実行時のネットワークを無効にし、この例ではポートも公開しません。ビルド時のイメージ取得とは別の指定です。

--cpus 1と--memory 128Mは実行時のリソース制限です。環境によってswapの制限に対応しないという警告が出ることがあり、メモリー指定だけでswapまで制限できるとは限りません。

Windowsのフォルダーへ結果を書き出す

コンテナー内だけへ保存したファイルは、--rmでコンテナーを削除すると失われます。Windows側に成果物を残したい場合は、作業用のフォルダーをbind mountで渡すと、コンテナーから直接そこへ書き出せます。

引き続き同じPowerShellで実行してください。shareはこのサンプル専用の新しいフォルダーです。Resolve-Pathで絶対パスにしてから、コンテナー側の/dataへ接続します。

New-Item -ItemType Directory -Path './share' -ErrorAction Stop | Out-Null
$sharePath = (Resolve-Path -LiteralPath './share').Path
$mount = "type=bind,source=$sharePath,target=/data"
wslc run --rm --network none --cpus 1 --memory 128M --mount $mount wslc-file-demo:1 /bin/sh -c 'printf "saved by container\n" > /data/result.txt; cat /data/result.txt'
saved by container

イメージ名の後にコマンドを書いたので、この起動ではCMDの代わりにファイルを書き出す処理が動きます。result.txtを保存したあと、catでその内容を表示しています。元のhello.shやイメージを書き換える操作ではありません。

コンテナーが終了してから、Windows側でも内容を読めます。

Get-Content -LiteralPath './share/result.txt'
saved by container

同じ文字列が表示されれば、コンテナーからWindowsの専用フォルダーへ書き出せています。bind mountは既定で書き込み可能なので、個人のドキュメント全体ではなく、必要な作業フォルダーだけを渡すのが扱いやすい方法です。このコマンドを再実行するとresult.txtは上書きされます。

ファイルの保存場所を選ぶ

スクリプトを変えて実行内容を更新したいときは、hello.shを編集してから、同じbuildコマンドでイメージを作り直してください。COPYで取り込んだファイルは、そのビルド時点の内容です。

一方、実行結果をWindowsで使いたいときは、今回の/dataのように共有先へ保存します。コンテナーの削除と成果物の保存を別々に考えられるので、単発の変換や小さなスクリプトから試しやすくなります。コンテナー自身の書き込み領域は長期保存のバックアップ代わりにせず、残したいファイルの保存先を決めておくと安心です。

WSL containersの位置付けやWSL 2との番号の違いは、WSL 3.0の変更点でも説明しています。

参考:Microsoft Learn:WSL containersのビルドと実行、Docker Docs:bind mountの保存先と書き込み権限。