Bot mmnot

🛠️開発記録#202(2025/4/28)MMbot開発ログ10「Makefile + .env で開発を進めるメリットとそのやり方」—— 個人開発でも“運用コスト激減”を実感できる環境分離術

2025年4月28日

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

この記事では、私が 仮想通貨トレード Bot(MMBot) を作る過程で
実際に導入して効果を感じた Makefile環境変数ファイル(.env) の組み合わせを、
“完全初心者でも今日から真似できる” レベルで解説します。


対象読者

  • 「動くスクリプトは出来たけど、テスト/本番を切り替えるたびに書き換えが面倒」
  • 「 API キーや URL をハードコードしていて怖い」
  • 「将来 CI/CD やチーム開発も見据えて整えておきたい」

1. Makefile と .env の役割を 1 分でつかむ

何をするもの?例え
.env**変わりやすい値(キー・URL・パラメータ)**をファイルで切り替える材料セット(和風・洋風など具材を袋にひとまとめ)
Makefile手順書をコマンド化するオーダー票(今日は和風で!と厨房に伝える紙)

つまり

  • レシピ本(Python コード)は一切触らず、
  • 材料セット(.env)とオーダー票(Makefile)を入れ替えるだけで
  • テストコース⇆本番コースをワンコマンドで出し分けできる仕組み
    というわけです。

2. .env.test / .env.prod を用意してみよう

# .env.test — テストネット用 (例)
MODE=test
SYMBOLS=ETHUSDT,BTCUSDT
BYBIT_KEY_TEST=xxxxxxxx
BYBIT_SECRET_TEST=yyyyyyyy
DEFAULT_LEVERAGE=10
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXXX/...
# .env.prod — 本番用 (Git管理しない!!)
MODE=main
SYMBOLS=BTCUSDT,ETHUSDT
BYBIT_KEY_MAIN=********
BYBIT_SECRET_MAIN=********
DEFAULT_LEVERAGE=10
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YYYY/...
  • .env.prod.gitignore に必ず追加
echo ".env.prod" >> .gitignore
  • どちらも キーバリューペア をシェルスクリプト形式で書くだけ。

Python 側は特に変更不要。従来どおり os.getenv("BYBIT_KEY_TEST") などで取得できます。


3. Makefile で「コマンド丸ごと一行化」

# Makefile(プロジェクト直下)

SHELL := /bin/bash

run-loop = \
  set -a && source $(1) && set +a && \
  ./run_loop.sh          # ← 既存の Bash スクリプトを呼び出す

.PHONY: testnet-loop mainnet-loop keycheck

testnet-loop:
	@$(call run-loop,.env.test)

mainnet-loop:
	@$(call run-loop,.env.prod)

keycheck:
	@grep -E "BYBIT_KEY_|BYBIT_SECRET_" .env.* | sed 's/=.*/=<hidden>/'

ポイントは 3 行だけ。

  1. set -a && source $(1)
    .env.* を「export 付き」で読み込み、Python 側に渡す
  2. run_loop.sh に長いオプションを全部書いておく
  3. ターゲット名=運用モード
    make testnet-loop / make mainnet-loop で環境が切り替わる

4. 実戦投入:テストネット→本番切替え

make keycheck       # キーが入っているかマスク表示で確認
make testnet-loop   # テストネットでぐるぐる検証
# └ Slack通知 / trades.db に fill が入るか見る

make mainnet-loop   # 本番最小ロットで稼働開始!

コードは 1 行も触っていません。
変えたのは .env.* と Makefile の呼び出し先だけ。


5. よくあるハマりどころ & デバッグ術

症状原因 & 対策
No such file or directory: .env.testMakefile と .env.* が別フォルダ → 相対パスを合わせる
Permission denied ./run_loop.shchmod +x run_loop.sh を忘れがち
Slack がエラー invalid_webhookURL がダミー/空。make keycheck で再チェック
本番で API key invalid.env.prod にテスト用キーを入れていた → キーを差し替えて再実行

6. さらに便利にするアイデア集

アイデアどう便利?
make env-check必須変数が空なら起動前に落とす (grep -v '=' .env.test)
make lint / fmt / testコード品質ターゲットも一緒に管理
CI/CDmake testnet-loop -n-n (dry-run) でコマンド生成だけテスト
シェル変数で上書きLOT=0.01 make mainnet-loop ← 一時的ロット変更

7. まとめ:スクリプトを“資産化”する第一歩

  • .env で「環境依存値」を切り離す
    → キー漏えい防止・モード切替が 1 行
  • Makefile で「手順書」をボタン化
    → 再現性と可読性が飛躍的アップ
  • コードはそのまま運用だけ柔軟に
    → 機能追加や CI/CD 対応時の修正コストが激減

これを導入しただけで、
テストネット検証 ⇒ 本番デプロイ を“1 行+ファイル切替”で回せるようになりました。
初心者ほど効果を感じやすいので、ぜひ明日の開発から取り入れてみてください。

おまけ:Makefile + .env 分離方式 ― 想定しておくべきデメリットと注意点

デメリットどういう場面で表面化する?最小限に抑えるコツ
① “Makefile 依存” が増え、他 OS/ツールの人が戸惑うWindows 環境には make が入っていないことが多い- make が無い場合は GNU make バイナリを同梱するか、justfile / npm scripts など代替を提示
- README 冒頭で「まず --> make install」と書く
② 行頭タブ・パスの落とし穴タブをスペースに置換 → “Missing separator” エラー
相対パスを動かすたびに修正が必要
- VS Code などで「Makefile はタブ保存」を設定
- PROJECT_ROOT=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 等でパスを変数化
.envps aux に環境変数で丸見え問題source .env && …プロセス環境に平文キーが載る → OS のプロセス一覧で盗み見可能- 本番運用は direnv allowsystemd EnvironmentFile= に切り替え
- 重要キーは KMS / Secret Manager へ移し、起動時にインジェクション
.env.prod を誤って Git に push しうるチーム開発者が .gitignore を削除/別名で作成 → 秘密漏えい- CI でシークレット文字列を自動スキャン(truffleHog など)
- .env.prod.example(中身空)を置き、実ファイルは別名にする運用
⑤ 変数の型・桁数チェックが手動例:LOT=0.1a と書いても make は通る → 実行時に API で落ちる- make env-check ターゲットを作り、正規表現でバリデーション
- Python 起動前に bash -eu で必須項目と数値範囲を assert
**⑥ プロセスごとに .env を source するため fork/exec が遅くなる1 秒未満だが超高頻度バッチだと無駄オーバーヘッド- Bot のような長時間プロセスでは問題になりにくい
- もし気になるなら systemd 環境変数で一度だけ読み込む
⑦ “環境ファイルが増えすぎ問題”ステージ・地域・テストケース… .env.stg.sgp など乱立- 3 層程度に留める(dev / test / prod)
- それ以上は dotenv + CLI 引数 で上書き or Secrets Manager を採用

どう判断すればいい?

  • 個人〜小規模開発
    • Makefile+.env は 導入コスト<得られる時短効果 が大きい。
    • 上のデメリットも「自分だけが触るサーバー」ならほぼ気にならない。
  • チーム開発・長期運用
    • セキュリティ運用(秘密管理)CI/CD と整合 を追加検討。
    • Makefile は「ローカル便利ツール」と割り切り、本番は systemd + Ansible で流すなど役割分担を明確にする。

要するに
Makefile+.env は「スクリプトを壊さず環境だけ変える最短の仕組み」ですが、
秘密の扱いタブ/パスの罠にだけ注意すれば、
初学〜中規模の Bot 開発ではメリットの方が圧倒的に大きい、ということです。

👇ラジオで話したこと

こんにちは、よだかです。
今日は 「Makefile と .env ファイル」 を使って、
テストネット⇆本番ネットを“コードを1文字も変えず”に切り替える方法を解説します。

対象は

  • スクリプトは動くけどモード切替で毎回ソースを直している人
  • APIキーをハードコードしてしまいビクビクしている人
  • いつか CI/CD や複数人開発を視野に入れたい人

.env と環境変数――「材料セット」とは何者?

  • 1:環境変数って?
    • OS が覚えてくれる メモ欄。例:API_KEYDB_URLMODE
  • 2:.env ファイルは“材料セット。料理で言えば テスト用の具材袋。本番用は別袋。
MODE=test
BYBIT_KEY=xxxx
  • 3:Python との橋渡し
    • source .env.test で袋を開け、
    • OS が材料を作業台(環境変数テーブル)へ並べる。
    • Python は os.getenv("BYBIT_KEY") でサッと取るだけ。

🖼 1行図

(.env.test か .env.prod) ──source→ 作業台 ──exec→ Python ← os.getenv()

② Makefile――「オーダー票」がやる3つの仕事

仕事料理のたとえ実際にすること
1️⃣ どの袋を開けるか決定「今日は和風で!」.env.test.env.prod を選ぶ
2️⃣ 材料を並べる食材をカウンターへset -a && source … で輸送
3️⃣ レシピを実行シェフに一括指示./run_loop.sh を起動

結果、開発者は make testnet-loopmake mainnet-loop
――“オーダー票を出す” だけでOK。


.env.test.env.prod を作ってみる

# .env.test          # テスト用材料
MODE=test
BYBIT_KEY_TEST=xxxx
…

# .env.prod          # 本番用材料(Git管理しない)
MODE=main
BYBIT_KEY_MAIN=****
…
  • .env.prodecho ".env.prod" >> .gitignore を忘れない。
  • Python 側はすでに os.getenv() を使っているなら修正ゼロ

「.env.prod を .gitignore に入れ忘れると何が起こる?」

本番用の .env.prodecho ".env.prod" >> .gitignore――
これ、絶対に外せない“1行” です。なぜ か、掘り下げます。


1️⃣ 公開リポに push = キーがインターネットへ放流

  • GitHub や GitLab に commit した瞬間、数分でクローラーがスキャン
  • 奪われた API キーは
    • 勝手トレード → 資産ロス
    • 相場操作の片棒 → 帳簿が真っ赤
    • 有料 API なら課金爆増 …と被害が連鎖。

2️⃣ 履歴から消しても URL が残る

  • git reset で戻しても 過去コミットの URL は永久に残る
  • 「消したつもり」が通用しない世界なので、
    “そもそも push させない” が唯一の防御。

3️⃣ チーム開発だと “芋づる事故” が起きる

  • A さんが .env を push → B さんが fork → C さんが再公開。
  • 誰か1人のミスが全員の秘密情報を汚染します。
  • .gitignore は“安全柵”、柵が無い牧場は牛が逃げると思ってください。

4️⃣ 最低限の安全3点セット

  • 1:.gitignore に本番 .env を追加
echo ".env.prod" >> .gitignore
  • 2:.env.prod.example を空ファイルで置く
    → フォーマットは共有しつつ中身は空。
  • 3:秘密スキャンツール(例 truffleHog)を pre-commit/CI に導入

「鍵の吹きこぼれチェック」を自動化して、
“人間の凡ミスをシステムで塞ぐ”——これが鉄則です。


🎤「まとめると、『.env.prod は push させない』――
この1行は資産を守る“防波堤”。忘れず立てておきましょう!」


④ ワンコマンド実演

make keycheck      # 材料袋の中身をマスク表示で確認
make testnet-loop  # テストネットでぐるぐる
make mainnet-loop  # 本番に切替えて最小ロット稼働

レシピ本(Python)は触っていません。
変えたのは “材料セットをどれにするか” と “オーダー票の行” だけ。


⑤ トラブル TOP3 と秒速レスキュー

現象原因即対応
*** missing separatorMakefile 行頭タブがスペース化エディタで “Makefileはタブ保存”
Permission denied run_loop.sh実行権限なしchmod +x run_loop.sh
.env がGitにpush.gitignore 抜けtruffleHogで秘密スキャン+*.example運用

ここからは、私が MMbot を作る途中で実際に踏んだ落とし穴だけ をご紹介。全部“手グセ”レベルで直せるものばかりです。

1️⃣ *** missing separator——タブ地獄

  • 状況
    Makefile を VS Code で保存 ⇒ 赤文字エラー。
    原因 = 行頭タブがスペースに置換。
  • 秒速レスキュー
    1. VS Code 設定検索 →
      "editor.insertSpaces": falseMakefile スコープで追加。
    2. ファイルを再保存。──5秒で復活

2️⃣ Permission denied ./run_loop.sh——実行権限忘れ

  • 状況
    Git に新しいシェルを追加 → サーバで走らず止まる。
  • 秒速レスキュー
chmod +x run_loop.sh
git add run_loop.sh
git commit --amend
  • 以後、pre-commit フックで chmod +x を自動付与。
  • chmod = change mode
    +x = 実行権を足す
    これで「シェルスクリプトやバイナリを“クリックできる状態”にする」

3️⃣ Slack で invalid_webhook——URL貼り間違い

  • 状況
    テスト通知が飛ばず “invalid_webhook” エラー。
    コピー時に末尾改行が混入していた。
  • 秒速レスキュー
    1. make keycheck.env.testマスク付き表示
    2. Webhook をコピペし直し完了。
      以後、.env 生成時は QR「Quick Replace(=雑なコピペ)」 で貼り付け禁止 ルールを自分に課す。

便利ワザ2つ(私が本当に使っているもの)

コマンド実際どう助かっている?
make env-check起動前に .env の必須キーを grep。空なら即 Abort。「必須の材料が入っていなければ、鍋を火にかける前に止める」
「キー抜け → 403 で真っ赤」ゼロ になりました。
LOT=0.02 make mainnet-loop一時ロットだけ上書きして小額ライブ検証。
ファイルを汚さず “本番で小さく試す” のが激ラク。

🎤「以上が実体験ベースの落とし穴3+便利ワザ2
ここを押さえるだけで、デバッグ時間は体感で半分になります。
ぜひ明日の開発から取り入れてみてください!」


まとめ & 次回予告

今回は.envとMakefileについてのお話でした。

材料セット(.env)オーダー票(Makefile) を分けるだけで
テスト⇆本番を ワンコマンド で切替え、鍵漏えいも防げるということです。

ぜひ、開発の参考にしてみてください。

🎙️おまけトーク(実話ベース)
「.env を Git に晒したら資産30%が蒸発――他人の失敗に学ぶ」

【事例のあらすじ】

  • 2022 年12 月、ボットサービス 3Commas から
    10 万件以上の取引所 API キーが流出。​Decrypt
  • 鍵を盗んだ犯人は “出金権限ナシ” でも資産を抜く裏ワザを使用。
    ① 自分が保有するマイナー銘柄を高値で売り注文
    ② 被害者アカウントに “成行買い” を連打
    ③ すぐに安値で買い戻し――差額を抜く という手口。
  • ある日本人トレーダー(Telegram被害者グループより)は
    口座残高の約30%(換算で2.4 BTC=約4万ドル)を3時間で失いました
    「850回の意味不明な売買履歴が残り、 気づいたときには手遅れだった」と証言。​Reddit

【なぜ起きたのか】

  1. もともと .env に API キー を保存 → 誤って GitHub公開リポへ push
  2. 攻撃者は GitHub の検索 API で “BYBIT_KEY=” をクローリング
  3. 3Commas 側で “自動インポート” できる JSON を生成し、
    数分でボット口座が乗っ取られた

ポイント:

  • 鍵は出金権限OFF でも “価格操作” で抜ける
  • GitHub は 公開=即クローラーに拾われる場所

【教訓と秒速ガードレール】

やること所要時間
echo ".env.prod" >> .gitignore3 秒
.env.prod.example を空で置く10 秒
truffleHog を pre-commit に入れる2 分
誤コミット時は キー即ローテーション即時

「秘密は push できる距離に置かない」
たったこれだけで “資産30%蒸発” を ゼロ円で防げる んです。



他人事に聞こえますが、コピペ1回で同じ落とし穴に落ちます。
皆さんの .gitignore、今すぐ覗いてみてください。

それではまた次回!よだかでした。

-Bot, mmnot