Windows 11のWSL2上に、Yocto LinuxをbitbakeするためのDockerコンテナを構築する手順です。
この手順は、実際にWSL2上でDockerイメージをビルドし、コンテナを起動できた構成を基にしています。ネイティブUbuntuとの差に起因する、Docker資格情報、UID/GID、Ubuntu 24.04既存ユーザー、Compose実行場所、BitBake環境初期化の問題も扱います。
関連ノート:
検証結果
次の構成でDockerイメージのビルドとコンテナ起動を確認済みです。
- ホスト:Windows 11 + WSL2 Ubuntu
- ベースイメージ:Ubuntu 24.04
- コンテナユーザー:
yocto- WSL側UID/GID:
1000/1001- イメージ:
local/yocto-build:ubuntu24.04- 作業ディレクトリ:
/work
1. ネイティブUbuntuとWSL2の違い
ネイティブUbuntu
Ubuntu
├─ Linux kernel
├─ ext4 filesystem
├─ Docker Engine
└─ Yocto build container
WSL2
Windows 11
├─ NTFS
├─ WSL2 VM
│ ├─ Linux kernel
│ ├─ ext4.vhdx
│ │ └─ /home/developer/yocto-docker-env
│ └─ Docker CLI / Docker Engine
└─ Docker Desktop(使用する場合)
WSL2では、ネイティブUbuntuにはない次の差異があります。
| 分類 | WSL2固有の注意点 |
|---|---|
| ファイルI/O |
/mnt/c経由のNTFSアクセスが遅い |
| Docker | Docker DesktopとWSL内Docker Engineが競合しやすい |
| 認証情報 | Windows用credential helperをLinux側から呼ぶ場合がある |
| UID/GID | WSLユーザーとコンテナユーザーの所有権を合わせる必要がある |
| Ubuntu 24.04 | ベースイメージにUID 1000のubuntuユーザーが存在する |
| リソース | CPU、メモリ、swapがWSL VM単位で制限される |
| ネットワーク | Windows、VPN、プロキシ、DNSの影響を受ける |
| QEMU | KVM、TUN/TAP、USBに追加制約がある |
2. 推奨ディレクトリ構成
Yocto関連データは、WSL2のLinuxファイルシステム上へ配置します。
/home/developer/yocto-docker-env
├─ docker/
│ ├─ Dockerfile.yocto-build
│ └─ compose.yaml
├─ workspace/
│ ├─ poky/
│ ├─ meta-openembedded/
│ └─ build-qemu/
├─ cache/
│ ├─ downloads/
│ └─ sstate-cache/
└─ artifacts/
避ける配置:
/mnt/c/Users/<user>/yocto-docker-env
/mnt/d/yocto-docker-env
Windows共有フォルダ上のbuild/tmp
NAS上のbuildディレクトリ
Yoctoは大量の小ファイルへアクセスするため、概念的には次の項が支配的になります。
$$
T_{build}=T_{CPU}+N_{file}( t_{I/O} + t_{scan} )
$$
- $N_{file}$:ファイル操作回数
- $t_{I/O}$:ファイルシステムの読み書き時間
- $t_{scan}$:Defenderなどの検査による追加時間
Yoctoでは $N_{file}$が非常に大きいため、1ファイルあたり数ミリ秒未満の追加遅延でも、合計すると無視できなくなります。/mnt/cではファイル1回当たりの遅延 $t_{I/O}$ が増えるため、$N_{file}$が大きいYoctoではビルド時間に大きく影響します。
3. 作業ディレクトリを作成する
WSL2 Ubuntu上で実行します。
cd ~
mkdir -p yocto-docker-env/{docker,workspace,cache/downloads,cache/sstate-cache,artifacts}
cd ~/yocto-docker-env
ext4上であることを確認します。
pwd
df -T .
期待例:
/home/developer/yocto-docker-env
Filesystem Type
/dev/sdX ext4
4. Docker実行方式を確認する
Docker Desktop連携と、WSL内Docker Engineを混在させないようにします。
which docker
docker context ls
docker version
docker info | sed -n '1,40p'
どちらか一方に統一する
- Docker DesktopのWSL Integrationを使用する
- WSL2 Ubuntu内へDocker Engineを直接インストールする
5. 完成版Dockerfile
~/yocto-docker-env/docker/Dockerfile.yocto-buildを作成します。
FROM ubuntu:24.04
ARG USERNAME=yocto
ARG USER_UID=1000
ARG USER_GID=1000
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gawk \
wget \
git \
diffstat \
unzip \
texinfo \
gcc \
build-essential \
chrpath \
socat \
cpio \
python3 \
python3-pip \
python3-pexpect \
python3-git \
python3-jinja2 \
python3-subunit \
xz-utils \
debianutils \
iputils-ping \
file \
locales \
libacl1 \
liblz4-tool \
zstd \
lz4 \
sudo \
ca-certificates \
curl \
rsync \
bc \
bison \
flex \
libssl-dev \
libelf-dev \
vim \
nano \
less \
tree \
tmux \
qemu-system-x86 \
qemu-system-arm \
qemu-system-aarch64 \
qemu-utils \
&& sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen \
&& locale-gen en_US.UTF-8 \
&& update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \
&& rm -rf /var/lib/apt/lists/*
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
# Ubuntu 24.04にはUID 1000のubuntuユーザーが存在するため、
# 同じUIDなら既存ユーザーをyoctoへ変更して再利用する。
RUN set -eux; \
test -n "${USER_UID}"; \
test -n "${USER_GID}"; \
test -n "${USERNAME}"; \
existing_group="$(getent group "${USER_GID}" | cut -d: -f1 || true)"; \
if [ -z "${existing_group}" ]; then \
groupadd --gid "${USER_GID}" "${USERNAME}"; \
fi; \
existing_user="$(getent passwd "${USER_UID}" | cut -d: -f1 || true)"; \
if [ -n "${existing_user}" ]; then \
usermod \
--login "${USERNAME}" \
--home "/home/${USERNAME}" \
--move-home \
--shell /bin/bash \
"${existing_user}"; \
usermod --gid "${USER_GID}" "${USERNAME}"; \
else \
useradd \
--uid "${USER_UID}" \
--gid "${USER_GID}" \
--create-home \
--shell /bin/bash \
"${USERNAME}"; \
fi; \
mkdir -p /etc/sudoers.d; \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" \
> "/etc/sudoers.d/${USERNAME}"; \
chmod 0440 "/etc/sudoers.d/${USERNAME}"
USER ${USERNAME}
WORKDIR /work
CMD ["bash"]
Dockerfileの要点
- パッケージインストールをユーザー作成より先に行う
-
sudoを先に導入し、/etc/sudoers.dを作成可能にする - Ubuntu 24.04の既存UID 1000ユーザーを再利用する
- WSL側とコンテナ側のUID/GIDを一致させる
-
CMDは1個だけ、JSON配列形式で記述する - BitBakeはrootではなく一般ユーザーで実行する
6. 完成版compose.yaml
~/yocto-docker-env/docker/compose.yamlを作成します。
services:
yocto-build:
build:
context: .
dockerfile: Dockerfile.yocto-build
args:
USERNAME: ${USERNAME:-yocto}
USER_UID: ${USER_UID:-1000}
USER_GID: ${USER_GID:-1000}
image: local/yocto-build:ubuntu24.04
container_name: yocto-build
hostname: yocto-build
working_dir: /work
tty: true
stdin_open: true
volumes:
- ../workspace:/work
- ../cache/downloads:/cache/downloads
- ../cache/sstate-cache:/cache/sstate-cache
- ../artifacts:/artifacts
7. Compose設定を検証する
Composeファイルがあるディレクトリへ移動します。
cd ~/yocto-docker-env/docker
設定を展開します。
USER_UID=$(id -u) \
USER_GID=$(id -g) \
USERNAME=yocto \
docker compose config
検証済み環境の例:
args:
USER_GID: "1001"
USER_UID: "1000"
USERNAME: yocto
Bashの
UIDへ代入しない
次は失敗します。UID=$(id -u) GID=$(id -g) docker compose build
UIDはBashの読み取り専用変数です。USER_UIDとUSER_GIDを使用します。
8. Dockerイメージをビルドする
cd ~/yocto-docker-env/docker
USER_UID=$(id -u) \
USER_GID=$(id -g) \
USERNAME=yocto \
docker compose build --no-cache
成功時の代表ログ:
[+] Building ... FINISHED
✔ Image local/yocto-build:ubuntu24.04 Built
9. コンテナを起動する
USER_UID=$(id -u) \
USER_GID=$(id -g) \
USERNAME=yocto \
docker compose up -d
確認:
docker compose ps
docker compose exec yocto-build bash
期待するプロンプト:
yocto@yocto-build:/work$
10. UID/GIDと書き込み権限を確認する
コンテナ内で実行します。
id
sudo id
pwd
検証済み構成の期待値:
uid=1000(yocto) gid=1001(yocto)
uid=0(root) gid=0(root)
/work
bind mountへの書き込み確認:
touch /work/test-write
touch /cache/downloads/test-write
touch /cache/sstate-cache/test-write
touch /artifacts/test-write
ls -ln /work/test-write
ls -ln /cache/downloads/test-write
所有者が1000 1001なら、WSL側とコンテナ側の権限が一致しています。
11. Pokyを取得する
WSL側またはコンテナ内の/workで取得します。
cd /work
git clone -b scarthgap https://git.yoctoproject.org/poky
使用するブランチは、プロジェクトのYoctoリリースと各meta-layerの対応ブランチへ合わせます。
12. BitBake環境を初期化する
bitbakeはDockerfileでグローバルインストールされるコマンドではありません。Pokyの環境初期化スクリプトでPATHへ追加されます。
cd /work
source poky/oe-init-build-env build-qemu
確認:
which bitbake
bitbake --version
期待例:
/work/poky/bitbake/bin/bitbake
コンテナへ入るたびに必要
新しいシェルでは、毎回source poky/oe-init-build-env build-qemuを実行します。
エイリアスを登録する場合:
echo "alias yocto-env='cd /work && source poky/oe-init-build-env build-qemu'" >> ~/.bashrc
source ~/.bashrc
次回から:
yocto-env
13. キャッシュを設定する
/work/build-qemu/conf/local.confへ追記します。
DL_DIR ?= "/cache/downloads"
SSTATE_DIR ?= "/cache/sstate-cache"
確認:
bitbake -e | grep '^DL_DIR='
bitbake -e | grep '^SSTATE_DIR='
期待値:
DL_DIR="/cache/downloads"
SSTATE_DIR="/cache/sstate-cache"
14. 最小イメージをBitBakeする
bitbake core-image-minimal
QEMU向け成果物の例:
find tmp/deploy/images/qemux86-64 -maxdepth 1 -type f | sort
エラー発生時
WSL2固有のエラー原因と対処は、WSL2_Docker_Yocto_トラブルシューティングのページを参照してください。
運用コマンド集
起動
cd ~/yocto-docker-env/docker
docker compose up -d
コンテナへ入る
docker compose exec yocto-build bash
Yocto環境を有効化
cd /work
source poky/oe-init-build-env build-qemu
停止
docker compose stop
削除
docker compose down
workspace、downloads、sstate-cacheはbind mountなので、コンテナを削除しても残ります。
完了判定チェックリスト
-
作業領域が
/home/...配下のext4にある - Docker DesktopまたはWSL内Docker Engineのどちらか一方を使用している
-
docker compose configでUID/GIDが空ではない - Dockerイメージを正常にビルドできる
-
yocto@yocto-build:/work$で起動できる -
idのUID/GIDがWSL側と一致する -
/workとキャッシュ領域へ書き込める -
source poky/oe-init-build-env build-qemuが成功する -
which bitbakeでBitBakeパスを確認できる -
DL_DIRとSSTATE_DIRが永続領域を指している -
bitbake core-image-minimalを開始できる
まとめ
WSL2上でYocto用Dockerコンテナを安定して構築する際の重要点は、次の4つです。
- Yocto作業領域をWSL2のext4上へ置く
- Dockerの実行方式を1つへ統一する
- WSL側UID/GIDとコンテナ側UID/GIDを一致させる
- Ubuntu 24.04の既存UID 1000ユーザーを考慮する
特にUbuntu 24.04では、既存のubuntuユーザーを無視してUID 1000のユーザーを新規作成すると失敗します。既存ユーザーを再利用する完成版Dockerfileを使用することで、WSL2上でもネイティブUbuntuに近い形でYoctoをBitBakeできる環境を構築できます。