Docker ビルド トラブルシューティングガイド
EvoSpikeNet-Core の Docker ビルドで遭遇する一般的な問題と対応方法をまとめました。
目次
ビルドの失敗
エラー: "Dockerfile: stage not found: runtime-wheel"
原因: Dockerfile が更新されていない、または Dockerfile に指定ターゲットがない
解決方法:
# Dockerfile で定義されているターゲットを確認
grep "^FROM.*AS runtime" Dockerfile
# 出力例:
# FROM runtime-base AS runtime-source
# FROM runtime-base AS runtime-wheel
# FROM runtime-base AS runtime-cython
# FROM runtime-base AS runtime-nuitka
# 4 つのターゲットすべてが定義されているか確認
docker build --target runtime -f Dockerfile . 2>&1 | head -20
修正例:
# Dockerfile が古い場合は最新版に更新
git pull
git checkout -- Dockerfile
# ビルド再試行
docker build --build-arg APP_IMAGE_MODE=wheel --target runtime-wheel .
エラー: "Cython compilation failed"
原因: 1. Cython がインストールされていない 2. C コンパイラがない 3. Python 開発ファイルがない
解決方法:
# Dockerfile のビルダーステージで Cython がインストールされているか確認
grep -A 5 "FROM python.*AS builder" Dockerfile | grep -i cython
# ローカルで問題を再現
docker build \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
--progress=plain \
.
Dockerfile で必要な修正:
# ビルダーステージで Cython を明示的にインストール
RUN pip install --no-cache-dir cython>=3.0 patchelf setuptools wheel
# コンパイラのインストール(Debian/Ubuntu)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
エラー: "Nuitka build failed: memory exhausted"
原因: Nuitka コンパイルにメモリ不足
解決方法:
# Docker デーモンのメモリ制限を確認
docker info | grep -i memory
# 制限を増やす場合は Docker 設定を編集
# ~/.docker/daemon.json
{
"memory": "8g",
"memory-swap": "8g"
}
# Docker デーモン再起動
systemctl restart docker
# 再ビルド試行
docker build \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
--memory=4g \
.
代替案:
# メモリが限定的な場合は Cython モードで代用
docker build \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
-t evospikenet:cython \
.
エラー: "No space left on device"
原因: ディスク容量が不足(Docker イメージレイヤーキャッシュがいっぱい)
解決方法:
# ディスク使用量確認
df -h /var/lib/docker/
# Docker ビルドキャッシュをクリア
docker builder prune -a
# または more aggressive に
docker image prune -a
docker volume prune
docker system prune -a
# 確認
df -h /var/lib/docker/
# ビルド再試行
docker build --no-cache -t evospikenet:fresh .
エラー: "ERROR: could not find a package with a matching specification"
原因: pip で指定されたパッケージが見つからない(依存バージョンの不一致)
解決方法:
# ビルドログで問題のあるパッケージを確認
docker build . 2>&1 | grep -i "not found\|error" | head -20
# pyproject.toml または requirements.txt で依存バージョン確認
cat pyproject.toml | grep -A 20 "dependencies ="
# 特定のパッケージバージョン修正例
# pyproject.toml で pin されたバージョンを柔軟に
# Before:
# torch==2.1.0
# After:
# torch>=2.0.0,<3.0
イメージのサイズ問題
問題: イメージサイズが異常に大きい
目安: - source: ~500MB(正常) - wheel: ~350MB(正常) - cython: ~400MB(正常) - nuitka: ~600MB(正常)
診断:
# イメージ全体のサイズ確認
docker images | grep evospikenet
# イメージの詳細分析
docker run --rm evospikenet:nuitka df -h /
# レイヤーごとのサイズ確認
docker history evospikenet:nuitka
# 不要なレイヤーを特定
docker run --rm evospikenet:nuitka du -sh /* 2>/dev/null | sort -h
解決方法:
# マルチステージビルドで中間ファイルを削除
FROM ubuntu:22.04 AS builder
RUN apt-get update && apt-get install -y build-essential \
&& apt-get clean && rm -rf /var/lib/apt/lists/* # ← ここが重要
FROM ubuntu:22.04 AS runtime
COPY --from=builder /opt /opt
キャッシュクリア:
# 特定イメージの中間ファイルを削除
docker image prune -a
# または Dockerfile で明示的にクリア
docker build --no-cache -t evospikenet:lean .
問題: イメージ内に不要なファイルがある
診断:
# イメージ内のファイル構成を確認
docker run --rm evospikenet:wheel find /opt/venv -type f -name "*.pyc" | wc -l
docker run --rm evospikenet:wheel find /opt/venv -type f -name "*.egg-info" -o -name "__pycache__" | wc -l
解決方法:
# Dockerfile でクリーンアップ
RUN pip install --no-cache-dir ... && \
find /opt/venv -type d -name __pycache__ -exec rm -rf {} + ; \
find /opt/venv -type d -name "*.egg-info" -exec rm -rf {} +
実行時エラー
エラー: "ImportError: cannot import name 'api'"
原因: Cython/Nuitka モードでモジュールが正しくコンパイルされていない
診断:
# イメージ内のモジュールを確認
docker run --rm evospikenet:cython python -c \
"import sys; print(sys.path); import evospikenet.api"
# .so ファイルが生成されているか確認
docker run --rm evospikenet:cython find /opt/venv -name "api*.so"
# 詳細なエラーを取得
docker run --rm evospikenet:cython python -v -c \
"import evospikenet.api" 2>&1 | tail -50
解決方法:
# スクリプトの実行ログを確認
docker build \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
--progress=plain \
. 2>&1 | grep -A 10 "protect_with_cython.py"
scripts/protect_with_cython.py の確認:
# スクリプト内で対象モジュールが正しく指定されているか確認
TARGET_MODULES = [
"evospikenet.api", # ← これらが実際に存在するか確認
"evospikenet.models",
# ...
]
エラー: "Segmentation fault" (Nuitka)
原因: Nuitka バイナリがビルドシステムと異なる Linux で動作している
診断:
# ベースイメージを確認
docker inspect evospikenet:nuitka | grep -i "FROM\|baseimage"
# バイナリの依存ライブラリ確認
docker run --rm evospikenet:nuitka ldd /tmp/nuitka-dist/evospikenet-api
解決方法:
# ビルド環境と同じベースイメージを指定
docker build \
--build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
# 異なる環境で実行する場合は再ビルドが必須
# 例: Ubuntu 20.04 で実行する場合
docker build \
--build-arg BASE_IMAGE=ubuntu:20.04 \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
エラー: "Connection refused" (API)
原因: コンテナ内の API サーバーが起動していない、またはポートが公開されていない
診断:
# コンテナ内で API が起動しているか確認
docker run --rm -p 18000:8000 evospikenet:source &
sleep 5
curl -v http://localhost:18000/health
解決方法:
# ポート公開を確認
docker run --rm -p 18000:8000 evospikenet:source
# API ログを確認
docker run --rm -e LOG_LEVEL=DEBUG evospikenet:source 2>&1 | tail -50
# docker-compose で確認
docker compose up -d api
docker compose logs api | tail -100
パフォーマンス問題
問題: ビルドが非常に遅い
原因: 1. Nuitka コンパイルは本質的に遅い(40~50 分) 2. Docker レイヤーキャッシュが効いていない 3. ディスク I/O が遅い
診断:
# 各ステップの実行時間を確認
docker build --progress=plain --target runtime-nuitka . 2>&1 | \
grep -E "^#[0-9]+ \[.*\] (DONE|RUN)" | head -20
解決方法:
# 1. キャッシュを活用
docker build --cache-from evospikenet:previous -t evospikenet:current .
# 2. 不要なステップをスキップ(開発中)
docker build \
--build-arg APP_IMAGE_MODE=wheel \
--target runtime-wheel \
-t evospikenet:dev .
# 3. Linux の場合、TMPFS を使用
mkdir -p /mnt/tmpfs
sudo mount -t tmpfs -o size=10G tmpfs /mnt/tmpfs
# Docker を /mnt/tmpfs に移動(オプション)
問題: 実行時に遅い(起動時間が長い)
計測:
# 起動時間を計測
time docker run --rm evospikenet:source bash -c "python -c 'import evospikenet.api'"
# 実行結果例:
# source: 0.5 秒
# wheel: 0.5 秒
# cython: 0.5 秒
# nuitka: 3-5 秒 (バイナリ起動のオーバーヘッド)
nuitka の起動時間を削減:
# バイナリをキャッシュ(コンテナ内)
docker run --rm -v nuitka-cache:/tmp/nuitka-dist evospikenet:nuitka
# 次回起動時にキャッシュを使用
docker run --rm -v nuitka-cache:/tmp/nuitka-dist evospikenet:nuitka
セキュリティ関連
問題: ソースコードが露出している(source モード)
これは仕様です。source モードは開発用です。
本番環境では:
# Cython または Nuitka モードを使用
docker build \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
-t evospikenet:prod .
問題: Cython .so ファイルが逆コンパイルされた
現実的なセキュリティ評価:
.soファイルは Python ソースよりも逆コンパイルが困難- 完全なセキュリティではなく難読化レベル
- 最高レベルのセキュリティは Nuitka(スタンドアロンバイナリ)
追加保護:
# 1. コンテナを読み取り専用に設定
docker run --read-only -v /tmp evospikenet:cython
# 2. ファイルシステムを暗号化
# 本番環境での全ディスク暗号化を推奨
# 3. イメージに署名を検証
cosign verify --key cosign.pub $REGISTRY/$IMAGE:$VERSION
問題: API キーが漏洩している
原因: 環境変数やファイルが Docker イメージに埋め込まれている
診断:
# イメージに API キーが含まれていないか確認
docker run --rm evospikenet:prod env | grep -i key
# Dockerfile で確認
grep -n "ARG.*KEY\|ENV.*KEY" Dockerfile
解決方法:
# ❌ 危険: ビルド時に指定
ARG API_KEY=secret123
RUN export API_KEY=$API_KEY
# ✅ 正しい: 実行時に指定
# Dockerfile では指定しない
# 実行時:
docker run -e API_KEY=secret123 evospikenet:prod
レジストリの問題
エラー: "denied: authorization failed"
原因: レジストリ認証情報が間違っている、または権限がない
解決方法:
# ログイン状態を確認
docker info | grep -i registry
# 再ログイン
docker login $REGISTRY
# ユーザー名とパスワード(またはトークン)を入力
# プッシュ再試行
docker push $REGISTRY/$IMAGE:$TAG
GitHub Container Registry (GHCR):
# Personal Access Token を生成
# GitHub → Settings → Developer settings → Personal access tokens → Generate new token
# スコープ: write:packages, read:packages, delete:packages
# ログイン
echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin
# プッシュ
docker push ghcr.io/$GITHUB_USERNAME/evospikenet:latest
エラー: "blob upload unknown"
原因: ネットワーク接続問題、レジストリのディスク容量不足
解決方法:
# ネットワーク接続確認
ping -c 5 $REGISTRY
# ローカルレジストリの場合、ディスク容量確認
docker exec registry df -h /var/lib/registry
# 再試行
docker push $REGISTRY/$IMAGE:$TAG --verbose
マルチプラットフォーム対応
問題: Linux ARM64 でビルドしたが AMD64 では動作しない
原因: プラットフォーム固有のバイナリ(Nuitka など)が混在している
診断:
# イメージのプラットフォーム確認
docker inspect evospikenet:nuitka | grep -i architecture
# ビルド対象プラットフォーム指定
docker build --platform linux/amd64 .
解決方法:
# マルチプラットフォーム対応ビルド
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
-t $REGISTRY/evospikenet:cython \
--push \
.
快速検査ツール
ビルド全モード検証スクリプト
scripts/validate-all-modes.sh:
#!/bin/bash
set -e
echo "🔍 Validating all Docker build modes..."
echo ""
MODES=(source wheel cython nuitka)
TARGETS=(runtime runtime-wheel runtime-cython runtime-nuitka)
RESULTS=()
for i in "${!MODES[@]}"; do
mode=${MODES[$i]}
target=${TARGETS[$i]}
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Building mode: $mode (target: $target)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
start_time=$(date +%s)
if docker build \
--build-arg APP_IMAGE_MODE=$mode \
--target $target \
-t evospikenet:validate-$mode \
./EvoSpikeNet-Core > /tmp/build-$mode.log 2>&1; then
end_time=$(date +%s)
duration=$((end_time - start_time))
echo "✅ Build succeeded (${duration}s)"
# テスト実行
if [[ "$mode" == "nuitka" ]]; then
if docker run --rm evospikenet:validate-$mode \
test -x /tmp/nuitka-dist/evospikenet-api; then
echo "✅ Binary validation passed"
RESULTS+=("$mode: ✅")
else
echo "❌ Binary not found or not executable"
RESULTS+=("$mode: ❌")
fi
else
if docker run --rm evospikenet:validate-$mode python -c \
"import evospikenet.api; print('✓ Import OK')"; then
echo "✅ Module import validation passed"
RESULTS+=("$mode: ✅")
else
echo "❌ Module import failed"
RESULTS+=("$mode: ❌")
fi
fi
else
echo "❌ Build failed"
tail -20 /tmp/build-$mode.log
RESULTS+=("$mode: ❌")
fi
echo ""
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Summary:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
for result in "${RESULTS[@]}"; do
echo "$result"
done
実行:
chmod +x scripts/validate-all-modes.sh
./scripts/validate-all-modes.sh
診断ツール
scripts/diagnose-docker.sh:
#!/bin/bash
echo "🔧 Docker Build Diagnosis"
echo ""
echo "1️⃣ Docker 環境"
docker --version
docker compose version
docker info | grep -E "Storage Driver|Runtimes"
echo ""
echo "2️⃣ ディスク容量"
df -h /var/lib/docker/
echo ""
echo "3️⃣ イメージキャッシュサイズ"
du -sh /var/lib/docker/image/
echo ""
echo "4️⃣ Dockerfile 確認"
echo "Targets found:"
grep "^FROM.*AS runtime" Dockerfile
echo ""
echo "5️⃣ ビルドスクリプト確認"
echo "Cython script:"
test -f scripts/protect_with_cython.py && echo "✓ Found" || echo "✗ Missing"
echo "Nuitka script:"
test -f scripts/build_nuitka_api_binary.py && echo "✓ Found" || echo "✗ Missing"
echo ""
echo "✅ Diagnosis complete"
実行:
chmod +x scripts/diagnose-docker.sh
./scripts/diagnose-docker.sh
関連リソース
- DOCKER_BUILD_MODES.md - ビルドモード詳細
- DOCKER_PUBLISHING_GUIDE.md - パブリッシングワークフロー
- CI_BUILD_MATRIX_GUIDE.md - GitHub Actions ワークフロー
- Docker 公式ドキュメント
- Dockerfile リファレンス