Docker ビルドモード完全ガイド
[!NOTE] このガイドは EvoSpikeNet-Core の Python ソースコード非公開パブリッシング機能について説明しています。
概要
EvoSpikeNet-Core は Docker イメージをビルドする際に、4つの異なるモードをサポートしています。 既存の開発フロー(完全なソースツリーを含む)を維持しながら、リリース時にはソース露出を段階的に削減できます。
| モード | 用途 | ソース公開 | ビルド時間 | 実行時サイズ | セキュリティ |
|---|---|---|---|---|---|
| source | ローカル開発・テスト | ✅ すべて | 短い | 大きい | なし |
| wheel | ステージング環境 | ❌ なし | 中程度 | 中程度 | 基本的 |
| cython | プリプロダクション | ❌ .so 化 | 長い | 中程度 | 中程度 |
| nuitka | 本番デプロイ | ❌ バイナリ化 | 最長 | 大きい | 高い |
1. source モード(デフォルト)
完全なプロジェクトソースツリーを含むイメージです。既存のすべての開発ワークフロー・テストと互換性があります。
用途
- ✅ ローカル開発・デバッグ
- ✅ CI/CD テストパイプライン
- ✅ 内部開発環境
- ✅ 後方互換性が必須な環境
セキュリティ特性
- リスク: Python ソースコードがコンテナ内で完全に公開される
- 対策: なし(意図的に、開発効率を優先)
- 推奨環境: 内部ネットワークのみ
ビルドコマンド
# 暗黙的(デフォルト)
docker build -t evospikenet:source .
# 明示的
docker build -t evospikenet:source \
--build-arg APP_IMAGE_MODE=source \
--target runtime \
.
実行例
# API サーバー起動
docker run --rm -p 18000:8000 evospikenet:source
# 対話型シェル
docker run --rm -it evospikenet:source bash
# ボリュームマウントでホットリロード
docker run --rm -p 18000:8000 \
-v $PWD/evospikenet:/opt/venv/lib/python3.10/site-packages/evospikenet \
evospikenet:source
ビルド検証
# イメージサイズ確認
docker images | grep evospikenet:source
# ソースコード確認(確認用)
docker run --rm evospikenet:source ls -la /app/evospikenet/api.py
推奨される docker-compose.yml 使用方法
version: '3.8'
services:
api:
image: evospikenet:source
ports:
- "18000:8000"
volumes:
- ./logs:/opt/venv/var/logs
environment:
- LOG_LEVEL=DEBUG
2. wheel モード
Wheel(.whl)形式で Python パッケージをビルドし、プロジェクトソースツリーをコンテナにコピーしないモードです。
用途
- ✅ ステージング環境への配布
- ✅ 内部レジストリでの配布
- ✅ ライセンス配布要件がある場合
- ✅ 基本的なソース保護が必要な場合
セキュリティ特性
- リスク: Python バイトコード(
.pyc)からのデコンパイルが可能 - 対策: プロジェクトソースツリーは除外される
- 保護レベル: 低~中程度(逆コンパイル対策なし)
ビルドコマンド
docker build -t evospikenet:wheel \
--build-arg APP_IMAGE_MODE=wheel \
--target runtime-wheel \
.
ビルド過程の詳細
builderステージで wheel を生成:pip wheel --wheel-dir /tmp/wheels .runtime-baseからruntime-wheelステージを構成- wheels のみをインストール:
pip install --no-index /tmp/wheels/* - プロジェクトソースツリー (
/app/evospikenet,/app/controllersなど) をコピーしない
実行例
# API サーバー起動
docker run --rm -p 18000:8000 evospikenet:wheel
# インストール済みパッケージ確認
docker run --rm evospikenet:wheel pip list | grep evospikenet
ビルド検証
# ホイルのインストール確認
docker run --rm evospikenet:wheel python -c \
"import evospikenet.api; print('✓ API module imported successfully')"
# ソースツリーが除外されていることを確認
docker run --rm evospikenet:wheel test -d /app/evospikenet && \
echo "WARNING: Source tree found" || echo "✓ Source tree correctly excluded"
# イメージサイズ比較
docker images | grep "evospikenet:source\|evospikenet:wheel"
イメージサイズの目安
- source: ~500MB (フルソースツリー含む)
- wheel: ~350MB (ソースツリー除外)
推奨される docker-compose.yml 使用方法
version: '3.8'
services:
api:
image: evospikenet:wheel
ports:
- "18000:8000"
read_only: true
security_opt:
- no-new-privileges:true
3. cython モード
選定されたモジュールを Cython でコンパイルし、.so(共有オブジェクト)ファイルに変換するモードです。
対応する .py ソースファイルはコンパイル後に削除されます。
用途
- ✅ プリプロダクション環境
- ✅ ソース難読化が必須な環境
- ✅ パフォーマンス最適化が必要な場合
- ✅ ライセンス保護が重要な場合
セキュリティ特性
- リスク:
.soファイルは逆コンパイル困難(ただし完全ではない) - 対策:
- 主要モジュールを C 拡張(
.so)に変換 - 元の
.pyファイルを削除 - C デバッグシンボルを取得困難にする
- 保護レベル: 中程度(専門の逆算出には対応不可)
Cython コンパイル対象モジュール
scripts/protect_with_cython.py で定義:
evospikenet/api.py
evospikenet/api_modules/distributed_brain_api.py
evospikenet/models.py
controllers/placement_controller.py
controllers/resource_controller.py
ビルドコマンド
docker build -t evospikenet:cython \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
.
ビルド過程の詳細
builderステージで wheel を生成(wheel モード同様)- wheel をインストール
- Cython コンパイル実行:
scripts/protect_with_cython.pyを実行 - 対象モジュールを検索
cythonize -3 -iでコンパイル.soファイルを生成- 元の
.pyファイルを削除 runtime-cythonステージで保護されたモジュールのみを含む
実行例
# API サーバー起動
docker run --rm -p 18000:8000 evospikenet:cython
# Cython コンパイル済みモジュール確認
docker run --rm evospikenet:cython find /opt/venv -name "*.so" | head -5
ビルド検証
# API モジュール動作確認
docker run --rm evospikenet:cython python -c \
"import evospikenet.api; print('✓ Cython-protected API module loaded')"
# .so ファイルの存在確認
docker run --rm evospikenet:cython python -c \
"import evospikenet.api; print(evospikenet.api.__file__)"
# 元の .py ファイルが削除されていることを確認
docker run --rm evospikenet:cython test -f /opt/venv/lib/python3.10/site-packages/evospikenet/api.py && \
echo "WARNING: Source file still exists" || echo "✓ Source file correctly removed"
ビルド時間
wheel コンパイル: ~5 分
+ Cython コンパイル: +10~15 分
= 合計: 15~20 分
イメージサイズの目安
- wheel: ~350MB
- cython: ~400MB (
.soファイルのため若干増加)
パフォーマンス影響
- 起動時間: ほぼ変わらず (プリコンパイル済み)
- 実行時: +5~10% 高速化の可能性 (Cython 最適化)
- メモリ使用量: ほぼ同等
推奨される docker-compose.yml 使用方法
version: '3.8'
services:
api:
image: evospikenet:cython
ports:
- "18000:8000"
read_only: true
security_opt:
- no-new-privileges:true
deploy:
resources:
limits:
memory: 2G
4. nuitka モード
Nuitka コンパイラを使用して、API サーバーを スタンドアロンバイナリに変換するモードです。 最高レベルのソース保護を提供しますが、ビルド時間と結果のイメージサイズが最大になります。
用途
- ✅ 本番環境での最大保護
- ✅ 商用デプロイメント
- ✅ ソースコード機密保持が最優先
- ✅ 規制環境での配布要件
セキュリティ特性
- リスク: コンパイル済みバイナリからのソース復元はほぼ不可能
- 対策:
- Python ランタイムをスタンドアロンバイナリ化
- すべての依存を embed
- 実行時のみ
.soファイルが生成される(一時領域) - 保護レベル: 高い(パッチングには再ビルドが必須)
ビルドコマンド
docker build -t evospikenet:nuitka \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
ビルド過程の詳細
builderステージで wheel を生成(wheel モード同様)scripts/build_nuitka_api_binary.pyを実行- 小型 Python ランチャーを作成
- Nuitka でコンパイル:
nuitka --onefileフラグ - スタンドアロンバイナリ生成:
/tmp/nuitka-dist/evospikenet-api runtime-nuitkaステージでバイナリのみを含む/app/launch.shがバイナリ起動
実行例
# API サーバー起動
docker run --rm -p 18000:8000 evospikenet:nuitka
# バイナリの存在確認
docker run --rm evospikenet:nuitka file /tmp/nuitka-dist/evospikenet-api
ビルド検証
# API バイナリが実行可能か確認
docker run --rm evospikenet:nuitka test -x /tmp/nuitka-dist/evospikenet-api && \
echo "✓ API binary is executable" || echo "ERROR: Binary not executable"
# イメージ内でのバイナリサイズ確認
docker run --rm evospikenet:nuitka du -sh /tmp/nuitka-dist/
# 起動時間を計測
time docker run --rm evospikenet:nuitka bash -c "timeout 5 /tmp/nuitka-dist/evospikenet-api || true"
ビルド時間
wheel コンパイル: ~5 分
+ Nuitka バイナリ化: +30~45 分
= 合計: 35~50 分
イメージサイズの目安
- wheel: ~350MB
- nuitka: ~600MB (バイナリとランタイムのため大きい)
パフォーマンス影響
- 起動時間: +2~3 秒(バイナリの起動オーバーヘッド)
- 実行時: +3~5% 高速化の可能性(Nuitka コンパイル最適化)
- メモリ使用量: +50~100MB (スタンドアロンランタイム)
注意事項
1. バイナリの可搬性
Nuitka バイナリはビルドシステムに依存します。異なる Ubuntu バージョンやアーキテクチャでは再ビルドが必須です。
# 事例: Ubuntu 22.04 でビルドしたバイナリは
# Ubuntu 20.04 では動作しない可能性がある
docker build --build-arg BASE_IMAGE=ubuntu:20.04 \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
2. パッチング戦略
Nuitka バイナリの脆弱性修正には再ビルドが必須です。
# 依存パッケージ更新後は再ビルド必須
pip install --upgrade <vulnerable-package>
docker build ... --no-cache --target runtime-nuitka ...
3. デバッグ機能の制限
スタンドアロンバイナリはデバッグが困難です。ログレベルを上げてデバッグしてください。
docker run --rm -e LOG_LEVEL=DEBUG evospikenet:nuitka
推奨される docker-compose.yml 使用方法
version: '3.8'
services:
api:
image: evospikenet:nuitka
ports:
- "18000:8000"
read_only: true
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
- /var/tmp
deploy:
resources:
limits:
memory: 3G
reservations:
memory: 2G
モード選択フローチャート
┌─────────────────────────────────────┐
│ Docker イメージ用途を決定 │
└─────────────────────────────────────┘
│
├─→ ローカル開発?
│ └─→ YES: source モード
│
├─→ 社内ステージング?
│ └─→ YES: wheel モード
│
├─→ ソース難読化が必須?
│ ├─→ YES: cython モード
│ └─→ NO: 次へ
│
└─→ 本番/商用デプロイ?
└─→ YES: nuitka モード
ビルドモード比較表(詳細)
| 項目 | source | wheel | cython | nuitka |
|---|---|---|---|---|
| ビルドコマンド | 明示的 | --build-arg APP_IMAGE_MODE=wheel --target runtime-wheel |
--build-arg APP_IMAGE_MODE=cython --target runtime-cython |
--build-arg APP_IMAGE_MODE=nuitka --target runtime-nuitka |
| ビルド時間 | ~2 分 | ~7 分 | ~20 分 | ~50 分 |
| イメージサイズ | 500MB | 350MB | 400MB | 600MB |
| 起動時間 | <1s | <1s | <1s | 3-5s |
| 実行速度 | 100% | 100% | 105% | 105% |
| デバッグ容易性 | ✅ 容易 | ⚠️ 困難 | ❌ 困難 | ❌ 困難 |
| ホットリロード | ✅ 可能 | ❌ 不可 | ❌ 不可 | ❌ 不可 |
| パッチング | ✅ 簡単 | ✅ 簡単 | ✅ 簡単 | ❌ 再ビルド必須 |
| ソース露出 | 完全 | なし | .so 化 | なし |
| セキュリティ | ⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 推奨環境 | 開発 | ステージング | プリプロ | 本番 |
トラブルシューティング
ビルドエラー: "permission denied while trying to connect to Docker daemon"
# Docker デーモン確認
docker ps
# 必要に応じて Docker 再起動
systemctl restart docker
ビルドエラー: "No space left on device"
Docker イメージビルドのためのディスク容量が不足しています。
# ディスク容量確認
df -h /var/lib/docker/
# クリーンアップ
docker builder prune -a
Cython モード: "cythonize not found"
Cython はビルドステージでのみ使用されます。docker build が正常に完了していない可能性があります。
# ビルドログ確認
docker build ... --build-arg APP_IMAGE_MODE=cython 2>&1 | tail -50
Nuitka モード: "Binary segmentation fault"
スタンドアロンバイナリが異なる Linux 環境で動作していない可能性があります。
# BASE_IMAGE を一致させて再ビルド
docker build --build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
イメージサイズが異常に大きい
Nuitka モード時に --onefile オプション処理が正常に完了していない可能性があります。
# イメージ内容確認
docker run --rm evospikenet:nuitka du -sh /tmp/nuitka-dist/
docker run --rm evospikenet:nuitka du -sh /opt/venv/
ベストプラクティス
1. 開発フロー
# ローカル: source モード
docker compose up -d api
# テスト環境: wheel モード
docker build -t myregistry.azurecr.io/evospikenet:wheel \
--build-arg APP_IMAGE_MODE=wheel \
--target runtime-wheel \
.
docker push myregistry.azurecr.io/evospikenet:wheel
2. リリースプロセス
# ステージング検証: wheel
# → OK なら cython へ移行
# → OK なら nuitka で最終ビルド
# → 本番環境へデプロイ
docker build -t evospikenet:v1.0-cython \
--build-arg APP_IMAGE_MODE=cython \
--target runtime-cython \
.
docker build -t evospikenet:v1.0-nuitka \
--build-arg APP_IMAGE_MODE=nuitka \
--target runtime-nuitka \
.
3. レジストリタグ戦略
# ビルドモードを明確にタグ付け
docker tag evospikenet:wheel myregistry/evospikenet:latest-wheel
docker tag evospikenet:cython myregistry/evospikenet:latest-cython
docker tag evospikenet:nuitka myregistry/evospikenet:latest-nuitka
# バージョン + モードで管理
docker tag evospikenet:nuitka myregistry/evospikenet:v1.0.0-nuitka
4. セキュリティ設定
# docker-compose.yml(本番環境推奨)
services:
api:
image: evospikenet:nuitka
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
tmpfs:
- /tmp
- /var/tmp
関連ドキュメント
- DOCKER_PUBLISHING_GUIDE.md - 本番環境へのパブリッシング手順
- DOCKER_BUILD_GUIDE.md - 既存の docker-compose ビルド方法
- README.md - プロジェクト全体の概要