📚

Dockerfileの「ENV PYTHONDONTWRITEBYTECODE 1」について【初心者向けの記事】

2025/01/12に公開

今回は、前回に引き続き、
dockerfileの設定についてまとめました。

dockerfile
ENV PYTHONDONTWRITEBYTECODE 1

dockerfileに「ENV PYTHONDONTWRITEBYTECODE 1」と記載することで、

  1. Pythonが.pycファイル(コンパイル済みのPythonコード)を生成するのを防ぎます
  2. .pycファイルはキャッシュとして使われますが、不要なディスク容量を使用し、時にデバッグを複雑にすることがあります
  3. イメージのサイズを小さく保つのに役立ちます

3.は何となく理解できるのですが、
1と2について、もう少し掘り下げて説明をまとめてみました。

.pycファイルが生成されると何がマズい?

「ENV PYTHONDONTWRITEBYTECODE 1」
と記載することで、
「Pythonが.pycファイル(コンパイル済みのPythonコード)を生成するのを防ぐ」

ということなのですが、作られると何がマズいのでしょうか?

ディスク容量の無駄使い

  • 各.pyファイルに対して.pycファイルが生成される
  • アプリケーションが大きい場合、容量が倍近くになることも
  • コンテナ環境では軽量さが重要なため、望ましくない

ビルド時間の増加

Dockerイメージのビルド時に全ての.pyファイルに対して
.pycを生成する時間が必要となり、
CI/CDパイプラインなどでの実行時間が長くなる

・・・内容がわかりかけていたところに、
「CI/CDパイプライン」と
またわからん用語が出てきてしまう流れに(笑)

CI/CDパイプラインとは?

ソフトウェア開発における自動化された一連の流れのこと。

CI (Continuous Integration: 継続的統合)

開発者が書いたコードを定期的に統合する仕組み
例えば:

  • コードが追加されるたびに
  • 自動的にテストを実行
  • コードの品質チェック
  • ビルドの確認

CD (Continuous Delivery/Deployment: 継続的デリバリー/デプロイメント)

テスト済みのコードを本番環境に届けるための仕組み
例えば:

  • テストが通ったコードを
  • 自動的にステージング環境にデプロイ
  • 最終確認後に本番環境にデプロイ

実際の流れの例:

  1. 開発者がコードを書いてGitHubにプッシュ
  2. 自動的にテストが実行される
  3. コードの品質がチェックされる
  4. Dockerイメージが自動的に作られる
  5. テスト環境にデプロイされる
  6. 問題なければ本番環境にデプロイされる

これら全ての工程が自動化された「パイプライン」として繋がっているため、
「CI/CDパイプライン」と呼ばれます。

デバッグを複雑にする「ことがあります」

と、曖昧な表現が気になったので調べてみました。

ソースコードの変更が反映されない場合がある

  • .pycファイルがキャッシュとして残っていると
  • .pyファイルを修正しても、古い.pycが読み込まれて
  • 変更が反映されていないように見える

エラーメッセージの行番号が不正確になる可能性

  • エラーが発生した際のスタックトレースが
  • .pycファイルの行番号を参照することがあり
  • 実際の.pyファイルの行番号と一致しない場合がある

複数バージョンの混在

  • 異なるPythonバージョンで作られた.pycファイルが
  • 同じディレクトリに存在する可能性があり
  • 予期せぬ動作の原因となることがある

そのため、開発・デバッグ時は特に
.pycファイルの生成を無効にすることが推奨されます。

ということでした。
上記の内容は、Visual Studio C++の開発をやっていた時に、
全体的に同じようなことが起きたことがあった記憶があるので、
何となく解説がしっくりきました。

逆に、.pycファイルの生成を有効にしたほうがいい場合とは?

  1. 本番環境での実行速度を重視する場合
  • .pycファイルは事前コンパイル済みなので、起動時の実行が高速
  • 特に大規模なPythonアプリケーションで効果が出やすい
  • サーバーの起動時間を短縮したい場合に有効
  1. ソースコードの保護が必要な場合
  • .pycファイルは.pyファイルより解読が困難
  • 商用アプリケーションでソースコードを配布したくない場合
  • ただし、完全な保護ではないことに注意
  1. リソースに余裕があり、パフォーマンスを最優先する場合
  • メモリやディスク容量に制約がない環境
  • 実行速度の最適化が最優先
  • 開発環境ではなく、安定した本番環境での運用

ただし、以下の点に注意が必要です。

  • Dockerコンテナでは通常、軽量さを重視するため無効にすることが多い
  • デバッグのしやすさと開発の効率性とのトレードオフを考慮する必要がある
  • マイクロサービスなど、起動時間が重要な場合は有効化を検討する価値がある

Discussion