Docker Containers ガイド#
このガイドは、Docker と Docker Compose の基本知識がある方向けに、実際のプロジェクト開発で Containers をどのように使うかを説明しています。
前提知識
Docker と Docker Compose の基本的な理解
docker compose runなどの基本コマンドターミナルでのファイル操作
はじめに:何ができるのか?#
Haniwers では、Docker Containers を使用して以下のことが可能です:
✅ テスト環境の隔離: ホスト環境に影響なくテスト実行
✅ 環境の統一: 開発者全員が同じ環境でテスト実行
✅ 依存関係の管理: Poetry でビルドされた完全な環境
✅ 複数のワークフロー: CLI テスト、ドキュメント生成、ユニットテスト
ディレクトリ構成#
haniwers/
├── compose.yaml ← プロジェクトルートのプロキシ
├── containers/
│ ├── compose.yaml ← containers/ からのアクセス用
│ ├── .dockerignore ← ビルド時の除外設定
│ ├── dev/
│ │ ├── Dockerfile ← 開発・テスト用イメージ定義
│ │ ├── compose.yaml ← 実際のサービス定義
│ │ └── README.md
│ ├── python3/
│ │ └── compose.yaml ← PyPI パッケージ検証用
│ └── raspi/
│ └── Dockerfile ← Raspberry Pi デプロイ用
└── (その他のプロジェクトファイル)
クイックスタート#
最初の一度:イメージをビルド#
# プロジェクトルートで実行
docker compose build base
このコマンドで、haniwers:latest イメージが作成されます(初回は数分かかります)。
テストを実行#
# プロジェクトルートで実行
docker compose run --rm test
コンテナ内で pytest が実行され、すべてのテストが走ります。
CLI をテスト#
# Haniwers v0 のヘルプを表示
docker compose run --rm cli haniwers-v0 --help
# Haniwers v1 のポート一覧を表示
docker compose run --rm cli haniwers-v1 port list
ドキュメントを生成#
# ドキュメント生成
docker compose run --rm docs
実際の使用パターン#
パターン1: テストを実行してから開発#
新機能を開発する前に、テストが通ることを確認:
# 1. イメージが最新か確認
docker compose build base
# 2. テスト実行
docker compose run --rm test
# 3. テスト結果を確認
# → エラーが出た場合は修正
パターン2: コンテナ内で対話的にテスト#
デバッグのため、コンテナ内で bash シェルを使用:
# コンテナ内で bash を起動
docker compose run --rm test bash
# コンテナ内で実行:
[container] # poetry run pytest tests/v1/unit/helpers/ -v
[container] # poetry run haniwers-v1 version --env
[container] # exit
利点: ホスト環境に影響を与えずにコマンドを試行できます。
パターン3: ホストの変更をすぐにテスト#
ソースコードを編集してから、コンテナでテスト:
# ホストでファイルを編集
vim src/haniwers/v1/helpers/parser.py
# コンテナでテスト実行
docker compose run --rm test tests/v1/unit/helpers/test_parser.py -v
# → コンテナは自動でホストの最新コードを読み込みます
なぜ? compose.yaml で以下のようにマウントしているため:
volumes:
- ../../src/haniwers:/workspace/haniwers # ホストのコードをマウント
- ../../tests:/workspace/tests # テストをマウント
パターン4: 特定のテストだけを実行#
# 1つのテストファイルだけ実行
docker compose run --rm test tests/v1/unit/daq/device/test_connect.py
# 1つのテストクラスだけ実行
docker compose run --rm test tests/v1/unit/daq/device/test_connect.py::TestConnect
# 1つのテストメソッドだけ実行
docker compose run --rm test tests/v1/unit/daq/device/test_connect.py::TestConnect::test_connect_success
パターン5: ドキュメントを確認#
# ドキュメント生成
docker compose run --rm docs
# ブラウザで確認
# http://localhost:8000
よくある課題と解決方法#
課題1: イメージが古い#
新しい依存関係を追加した場合、イメージを再ビルド:
# イメージをクリーンビルド
docker compose build base --no-cache
課題2: コンテナ内で permission denied#
# エラー例:permission denied: /workspace/...
# 解決方法:コンテナ内で bash を実行して確認
docker compose run --rm test bash
[container] # ls -la /workspace/
課題3: ボリュームマウントが動作しない(macOS)#
Docker Desktop の設定を確認:
Preferences → Resources → File Sharing
プロジェクトのディレクトリが追加されているか確認
必要に応じて追加
課題4: コンテナが起動しない#
# エラーログを確認
docker compose config # 設定を確認
docker compose logs # ログを表示
各サービスの詳細#
base(ビルド)#
用途: イメージビルド専用
自動起動: なし(手動でビルド)
実行例:
docker compose build base
test(テスト実行)#
# 基本的なテスト実行
docker compose run --rm test
# 特定のテストスイート実行
docker compose run --rm test tests/v1/unit/
# カバレッジ付きテスト
docker compose run --rm test pytest --cov=haniwers
# 対話的なデバッグ
docker compose run --rm test bash
マウント:
src/haniwers/→/workspace/haniwerstests/→/workspace/testsdata/→/workspace/data
cli(CLI テスト・シリアルポート)#
# Haniwers v0 のヘルプを表示
docker compose run --rm cli haniwers-v0 --help
# Haniwers v1 のシリアルポート一覧を表示
docker compose run --rm cli haniwers-v1 port list
# Haniwers v1 のポートテスト
docker compose run --rm cli haniwers-v1 port test /dev/ttyUSB0
# バージョン確認
docker compose run --rm cli haniwers-v0 version
# 対話的にコマンドを実行
docker compose run --rm cli bash
[container] # haniwers-v1 daq --help
[container] # exit
マウント:
sandbox/→/workspace/sandbox/dev/→/dev/(シリアルポートアクセス有効)
特徴:
poetry runが自動的に実行される(entrypoint)ホストのシリアルポート(
/dev/ttyUSB*など)にアクセス可能privileged: trueでUSBデバイスアクセス権限を確保
dev(開発環境)#
# 開発環境で情報表示
docker compose run --rm dev
# コンテナ内で実行される内容:
# poetry run haniwers version --env
マウント:
src/haniwers/→/workspace/haniwerssandbox/→/workspace/sandbox
docs(ドキュメント生成)#
# ドキュメント生成
docker compose run --rm docs
# 生成されたファイル:
# docs/_build/dirhtml/ に HTML が生成されます
マウント:
src/haniwers/→/workspace/haniwersdocs/→/workspace/docs
Dockerfile について#
containers/dev/Dockerfile はマルチステージビルドを使用:
# Stage 1: Builder
FROM python:3.11-slim AS builder
RUN pip install poetry
# → Poetry で依存関係をインストール
# Stage 2: Runtime
FROM python:3.11-slim AS runtime
# → Builder の結果をコピー
# → ホストのコードをコピー
なぜ? イメージサイズを小さくしつつ、開発に必要なツールを含める
実践的なワークフロー例#
新機能を追加する場合#
# 1. 現在のテストが通ることを確認
docker compose run --rm test
# 2. 新しいコード/テストを作成(ホストのエディタで編集)
vim src/haniwers/v1/helpers/parser.py
vim tests/v1/unit/helpers/test_parser.py
# 3. 新しいテストだけ実行してみる
docker compose run --rm test tests/v1/unit/helpers/test_parser.py -v
# 4. すべてのテストが通ることを確認
docker compose run --rm test
# 5. コード品質をチェック
docker compose run --rm test bash
[container] # poetry run ruff format .
[container] # exit
# 6. コミット
git add ...
git commit -m "feat: add new feature"
テストがデバッグできない場合#
# 1. コンテナ内で bash を起動
docker compose run --rm test bash
# 2. コンテナ内で対話的にテスト
[container] # cd /workspace
[container] # poetry run pytest tests/... -v -s --pdb
# 3. デバッガーで問題を調査
# → exit で終了
CI/CD パイプラインでも同じ環境を使用#
# .gitlab-ci.yml で使用
image: python:3.11-slim
script:
- poetry install
- poetry run pytest
重要: ホストでの開発と CI/CD パイプラインで同じテスト環境を使用することで、「ローカルでは通るが CI では失敗」という問題を回避できます。
トラブルシューティング#
Q: コンテナ内のファイルがホストに反映されない#
A: コンテナ内で生成されたファイルは、マウントされているディレクトリにのみホストに反映されます。
# マウント設定の例
volumes:
- ../../data:/workspace/data # ホストの data/ にマウント
data/ に生成されたファイルはホストで見えます。/root/ などマウント外に生成されたファイルは見えません。
Q: poetry.lock が最新でない#
A: Dockerfile で依存関係がインストールされた時点の poetry.lock が使用されます。更新する場合:
# ホストで poetry.lock を更新
poetry update
# イメージをクリーンビルド
docker compose build base --no-cache
# テスト実行
docker compose run --rm test
Q: Python バージョンを変更したい#
A: Dockerfile を編集:
# FROM python:3.11-slim ← 3.11 を 3.12 に変更
FROM python:3.12-slim
# イメージをリビルド
docker compose build base --no-cache
参考資料#
containers/README.md - Containers ディレクトリの概要
containers/dev/README.md - 詳細な dev 環境設定
次のステップ#
テストガイドライン - テストの詳細な書き方
Mockerの使い方 - デバイスなしでのテスト方法
アーキテクチャ - コードの設計理解