Bot

開発記録#204(2025/5/1)MMbot開発ログ12「“環境まわり” の即効 Tips ―― pyenv × Poetry × Docker 連携メモ」

2025年5月1日

前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

1. Python バージョン管理:pyenv は “ホストで固定、コンテナで保証”

やったことTip
macOS 側を pyenv 3.12.4 に統一グローバル=3.12.4 に固定しておくと Poetrypython = "^3.12" と書くだけでズレない
poetry env use $(pyenv which python)Poetry の仮想環境が ホストと同じ minor になる → 依存ロックが1ファイルに集約

ポイント:ホストと Docker が同じ Python minor なら「動くのに本番で ImportError」の地雷を 99 % 排除できる。


2. 依存管理:Poetry の “dev / prod” グループ分離

[tool.poetry.group.dev.dependencies]
pytest = "*"
black  = "*"
mypy   = "*"
  • --without dev でイメージを 80 MB 以上スリム
  • GH Actions の CI パイプラインpoetry install (dev 付き) でテスト実行

3. Dockerfile:最小構成 + graceful shutdown

FROM python:3.12-slim

#--- poetry ---
RUN pip install --no-cache-dir poetry==1.8.2
ENV POETRY_VIRTUALENVS_CREATE=false

#--- project ---
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry install --no-root --without dev

COPY . .

# healthcheck / graceful stop
STOPSIGNAL SIGINT
CMD ["python", "MMbotbybit.py", "--mode", "mainnet"]
  • STOPSIGNAL SIGINTCTRL+Cdocker stopgraceful shutdown を強制
  • --without devビルド高速化 × 省メモリ

4. Compose プロファイル:testnetlive を 1 行切替

services:
  mmbot:
    profiles: ["${PROFILE:-testnet}"]   # ← `.env` で PROFILE 指定
    build: .
    env_file: .env.${PROFILE}
# テストネット
PROFILE=testnet docker compose up -d
# 本番
PROFILE=live    docker compose up -d
  • .env.testnet.env.live を分けるだけ
  • API キーの混線を物理的に防止 — 誤発注リスクがゼロに近づく

5. ユニットテスト:まず “副作用ゼロ” から書く

ステップ
1純関数 _calc_spread(bid, ask) をテスト
2DB / ネットワークを触る関数は pytest-mark slow で分離
3GH Actions で pytest -m "not slow" を自動実行

副作用なし関数に 10 行でもいいからテストを書く
それだけで「ロジック修正→実弾暴走」の事故が激減する。


6. ログ設計:INFO=JSONLines、DEBUG=テキスト

レイヤフォーマット理由
INFO (order filled, PnL, panic stop)JSONLGrafana / BigQuery にそのまま突っ込める
DEBUG (板差分など高頻度)プレーンテキストtail -f で即確認しやすい

7. 監視:Slack は“通知”、Prometheus は“俯瞰”

  • Slack:成功/失敗/緊急停止 だけを即時アラート
  • Prometheus + Grafana:CPU・メモリ・残高・PnL をダッシュボード化
    → “夜間放置” でも 10 秒で全体像が把握 できる

8. AI とのやり取りで詰まらなかったポイント

  1. PAT 認証エラー - ChatGPT に Docker login のフラグを即質問 → 解決
  2. execPrice KeyError - /execution/list への切替提案で 10 分短縮
  3. graceful shutdown シグナル - STOPSIGNAL SIGINT を提示され一発反映

上記の「問題 → AI への投げ方 → 得られた回答 → 修正結果」
は時系列で 3〜5 本まとめて、 “AI でデバッグを加速するコツ” として蓄積していくと良い。


まとめ

  • pyenv でホスト⇆コンテナの Python を揃える
  • Poetry の dev/prod 分離 で “肥満イメージ” を撃退
  • Compose プロファイル & STOPSIGNAL で「本番キー誤発注」と「ゾンビプロセス」を一掃
  • AI を“検索+対話型 Stack Overflow” として最短経路で活用

この4点を押さえるだけで、実弾デビュー前の環境トラブルは 8 割潰せます
ここまでできれば、次は live プロファイル で最小ロットを 24 h 放置 —— 安全ローンチへ進めることができます!

👇ラジオで話したこと

MMBot開発ログ #204|“環境まわり” の即効 Tips──pyenv × Poetry × Docker 連携メモ


こんにちは、よだかです。
今回のテーマは、Botを本番運用する前に欠かせない**「環境まわりの整備」**について。

タイトルはズバリ、
**「pyenv × Poetry × Docker 連携の即効Tips」**です。

初心者の方にも、開発中に起きがちな落とし穴を避ける方法
現場の手触りで紹介していきます。


1️⃣ Pythonのバージョンは“ホストとコンテナで揃える”

まず最初のポイントは Python のバージョン管理

pyenv × Poetry の組み合わせでホスト環境を固定し、
Docker コンテナでも同じ minor バージョン(例: 3.12)に揃える。

これで何が起きるか?

Poetry の仮想環境と Docker が一致することで、
✅ 「開発では動くのに、本番で ImportError」みたいな地雷が99%回避できるんです。


💡 実際の手順

pyenv install 3.12.4
pyenv global 3.12.4
poetry env use $(pyenv which python)

この3行で、ホストとPoetryの環境を揃えておきましょう。


2️⃣ Poetry の “dev / prod” 分離でイメージ最適化

次に、Poetryで依存ライブラリを“開発用と本番用”に分ける方法。

[tool.poetry.group.dev.dependencies]
pytest = "*"
black  = "*"
mypy   = "*"
  • 本番用の Docker イメージをビルドするときは:
poetry install --no-root --without dev

これでイメージが80MB以上スリムになり、起動も速くなります。

  • 一方で CI(GitHub Actionsなど)では --with dev を付けてテストも一緒に実行。

3️⃣ Dockerfile の工夫ポイント

ここは特に実践的な部分です。最小構成かつ安全に止まるよう設計しました。

FROM python:3.12-slim
RUN pip install --no-cache-dir poetry==1.8.2
ENV POETRY_VIRTUALENVS_CREATE=false
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry install --no-root --without dev
COPY . .
STOPSIGNAL SIGINT
CMD ["python", "MMbotbybit.py", "--mode", "mainnet"]

🧠 ここでのポイント:

  • STOPSIGNAL SIGINT
    docker stop や Ctrl+C でgraceful shutdownを実現。
  • --without dev
    → 本番ビルドは最軽量に。

4️⃣ Docker Compose で testnet / live を1行切り替え

複数環境を使い分けたいときは、Compose プロファイル+.envファイルが便利。

services:
  mmbot:
    profiles: ["${PROFILE:-testnet}"]
    env_file: .env.${PROFILE}

コマンドはこれだけ:

PROFILE=testnet docker compose up -d
PROFILE=live    docker compose up -d

✨ 効果:

  • .env.testnet / .env.live を物理的に分けることで、
    本番キーの誤発注リスクをゼロに近づけることができました。

5️⃣ ユニットテスト:副作用ゼロの関数から始める

「テストを書くのってハードル高そう…」という方へ。
まずは1行でもいいので副作用が無い関数からテストを書き始めましょう。

例:

def _calc_spread(bid, ask):
    return ask - bid

これだけでも pytest で簡単に検証できます。


✅ テストのステップ

  1. 純関数から始める
  2. DBやAPIを使う関数は pytest.mark.slow で分離
  3. CIでは pytest -m "not slow" だけを自動実行

→ これだけで 「コード変更 → 実弾暴走」の事故が激減します。


6️⃣ ログ設計:INFOはJSONL、DEBUGはプレーン

ログは目的によってフォーマットを使い分けるのが正解です。

レベルフォーマット理由
INFOJSONLBigQueryやGrafanaに直接突っ込める
DEBUGプレーンtail -f でリアルタイム監視しやすい

Botが本番で埋もれないように、重要ログはINFOに昇格、JSONLで出力が推奨です。


7️⃣ 監視:Slack通知+Prometheusで二層構成

通知系は即時と俯瞰を分けて設計します。

  • Slack:エラー/成功/パニックストップなど即時アラート
  • Prometheus+Grafana:P&L、残高、CPU使用率をダッシュボード化

→ 夜間放置でも、10秒でBotの健康状態を把握できるようになります。


8️⃣ AIとのやり取りで詰まらなかったこと

今回、AIを活用して即時解決できたことをいくつか紹介します。

問題AIの回答効果
Docker PAT 認証エラー--password-stdin を提示GitHub CIが通った
KeyError: execPrice/execution/list 切替を提案10分短縮
Graceful shutdownSTOPSIGNAL SIGINT を提案一発反映&安定停止

検索と違って、質問の意図まで汲み取ってくれるのがAIの強み。
→ 会話ログは後から “AIデバッグログ” として残しておくと非常に役立ちます。


まとめ&次のステップ

今回の開発ログでは、主に環境整備の即効テクニックを扱ってきました。
ここで振り返ると、押さえるべきポイントは4つです:


✅ 今日のまとめ(4点セット)

  1. pyenvでPythonバージョン統一(ホスト×Dockerのズレ排除)
  2. Poetryでdev/prod分離(スリムな本番イメージ)
  3. Composeプロファイル+STOPSIGNAL(誤発注とゾンビ対策)
  4. AIでデバッグ高速化(調べる→聞く→反映の最短ルート)

📍 ここまでできれば、“実弾デビュー前のトラブルの8割”は潰せます

次は live プロファイルで最小ロットを 24 時間放置。
いよいよ、安全ローンチフェーズへ進みましょう。



🎙️おまけ解説コーナー:

「今回出てきた用語、サクッと意味だけ押さえておこう」


はい、ここからはおまけ解説コーナー。
今回の開発ログで出てきた、ちょっと引っかかりそうな単語や表現を、
ざっくり・短く・ざっくり解説していきます。


🛑 STOPSIGNAL SIGINT(ストップシグナル・シグイント)

これは何?
Dockerに『コンテナを止めるときはこのやり方で止めてね』と教える設定。
SIGINT っていうのは Ctrl+C と同じ“終了指示”のことです。

→ これを設定しておくと、Botがパニック停止じゃなくて丁寧に止まってくれる=graceful shutdown。


🧩 Compose プロファイル & .env ファイル

「テストと本番を、1 行で切り替える仕組み」です。

.env.testnet.env.live みたいに分けておけば、
APIキーやSlackのURLが物理的に混ざらなくなる

PROFILE=live docker compose up -d

みたいに打つだけで、本番モードで起動できます。


🧮 純関数(じゅんかんすう)

**「外の世界に影響されない関数」**のこと。
同じ入力なら、いつでも絶対に同じ出力が返る。

例:def add(a, b): return a + b
→ テストがしやすく、バグも起きづらい。
まずはここからテストを書きましょうって話でした。


🧪 pytest(パイテスト)と pytest.mark.slow

pytestはPython用のテストツール
pytest test_my_func.py で自動的にテストしてくれます。

で、pytest.mark.slow
「このテストは重いよ」ってタグをつける仕組み。
CIでは -m "not slow" って指定すれば軽いテストだけ走らせられます。


🧠 BigQuery(ビッグクエリ)

これは Googleの超高速データベース
ログを全部突っ込んでおいて、SQLで集計したり分析したりできます。

Botが出す損益ログや取引履歴を機械学習にも使える形で残しておきたい人向けのツールです。


📄 JSONL(ジェイソンエル)とプレーンテキスト

  • JSONL:1行ごとに JSON を並べたログ形式。機械が読みやすい。BigQueryやGrafanaにそのまま渡せる。
  • プレーンテキスト:人間が目で追うための、ふつうの文字ログ。

INFOログはJSONL、DEBUGログはプレーン、これが使い分けの基本でした。


📡 tail -f(テイル・マイナス・エフ)

ログファイルの末尾をリアルタイムで見続けるコマンド」です。

tail -f mmbot.log

って打てば、ログの最新行が流れてくる。
Botがどう動いてるか、“今”の状況を監視するのに最適です。


🧪 DEBUG(デバッグログ)

ログの中でも「めっちゃ細かく中身を記録するモード」。

  • 開発中は DEBUG モードで
  • 本番は INFO モードで、って切り替えて使います。

Botが出す板差分とか注文情報とか、見えすぎて困る情報はDEBUGに振り分けます。


🔐 Docker PAT & --password-stdin

  • PAT:Personal Access Token(個人用トークン)
    GitHubのログイン用パスワード代わりに使う、安全な文字列です。
  • --password-stdin
    パスワードをコマンドの標準入力から受け取るというオプション。
    これを使えば、docker login 時にパスワードをターミナル履歴に残さないで済む=セキュリティ的に安全。

今回はちょっと用語多めでしたが、
“聞いたことあるけどちゃんと説明できないやつ”をこの場で一気に消化しておきました。

「動くインフラ」は「安心して戦略を試せる土台」です。
良き開発と、確かな運用を。次回もお楽しみに!
🎤 よだかでした。

-Bot