前回の記事に引き続き、今回も仮想通貨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 行だけ。
set -a && source $(1)
.env.*
を「export 付き」で読み込み、Python 側に渡すrun_loop.sh
に長いオプションを全部書いておく- ターゲット名=運用モード
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.test | Makefile と .env.* が別フォルダ → 相対パスを合わせる |
Permission denied ./run_loop.sh | chmod +x run_loop.sh を忘れがち |
Slack がエラー invalid_webhook | URL がダミー/空。make keycheck で再チェック |
本番で API key invalid | .env.prod にテスト用キーを入れていた → キーを差し替えて再実行 |
6. さらに便利にするアイデア集
アイデア | どう便利? |
---|---|
make env-check | 必須変数が空なら起動前に落とす (grep -v '=' .env.test ) |
make lint / fmt / test | コード品質ターゲットも一緒に管理 |
CI/CD で make 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)))) 等でパスを変数化 |
③ .env が ps aux に環境変数で丸見え問題 | source .env && … はプロセス環境に平文キーが載る → OS のプロセス一覧で盗み見可能 | - 本番運用は direnv allow や systemd 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_KEY
、DB_URL
、MODE
。
- OS が覚えてくれる メモ欄。例:
- 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-loop
か make mainnet-loop
――“オーダー票を出す” だけでOK。
③ .env.test
と .env.prod
を作ってみる
# .env.test # テスト用材料 MODE=test BYBIT_KEY_TEST=xxxx … # .env.prod # 本番用材料(Git管理しない) MODE=main BYBIT_KEY_MAIN=**** …
.env.prod
はecho ".env.prod" >> .gitignore
を忘れない。- Python 側はすでに
os.getenv()
を使っているなら修正ゼロ。
「.env.prod を .gitignore
に入れ忘れると何が起こる?」
本番用の .env.prod
は echo ".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 separator | Makefile 行頭タブがスペース化 | エディタで “Makefileはタブ保存” |
Permission denied run_loop.sh | 実行権限なし | chmod +x run_loop.sh |
.env がGitにpush | .gitignore 抜け | truffleHogで秘密スキャン+*.example 運用 |
ここからは、私が MMbot を作る途中で実際に踏んだ落とし穴だけ をご紹介。全部“手グセ”レベルで直せるものばかりです。
1️⃣ *** missing separator
——タブ地獄
- 状況
Makefile を VS Code で保存 ⇒ 赤文字エラー。
原因 = 行頭タブがスペースに置換。 - 秒速レスキュー
- VS Code 設定検索 →
"editor.insertSpaces": false
を Makefile スコープで追加。 - ファイルを再保存。──5秒で復活。
- VS Code 設定検索 →
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” エラー。
コピー時に末尾改行が混入していた。 - 秒速レスキュー
make keycheck
で.env.test
を マスク付き表示。- 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
【なぜ起きたのか】
- もともと .env に API キー を保存 → 誤って GitHub公開リポへ push
- 攻撃者は GitHub の検索 API で “
BYBIT_KEY=
” をクローリング - 3Commas 側で “自動インポート” できる JSON を生成し、
数分でボット口座が乗っ取られた
ポイント:
- 鍵は出金権限OFF でも “価格操作” で抜ける
- GitHub は 公開=即クローラーに拾われる場所
【教訓と秒速ガードレール】
やること | 所要時間 |
---|---|
echo ".env.prod" >> .gitignore | 3 秒 |
.env.prod.example を空で置く | 10 秒 |
truffleHog を pre-commit に入れる | 2 分 |
誤コミット時は キー即ローテーション | 即時 |
「秘密は push できる距離に置かない」
たったこれだけで “資産30%蒸発” を ゼロ円で防げる んです。
他人事に聞こえますが、コピペ1回で同じ落とし穴に落ちます。
皆さんの .gitignore
、今すぐ覗いてみてください。
それではまた次回!よだかでした。