Djangoのrunserverがつながらない?原因はWebpackでした
目次
- Djangoのrunserverがつながらない?
- 原因はDocker?
- ポートが間違っている?
- アドレスが間違っている?
- ポートが使用中?
- Pythonの組み込みサーバーを起動する
- プロジェクトが壊れている?
- settings.pyの読み込みはOK?
- ビジーの原因はだれ?
- 原因はWebpack関連だった
- おわりに
Djangoのrunserverがつながらない?
私の開発環境ではDockerとDjangoを組み合わせて使っています。
Dockerのコンテナを走らせて、そのコンテナ内でDjangoの開発用サーバーを起動し、ホストのブラウザでlocalhostにアクセスして開発中のWebサイトを表示していました。
先日も、あるアプリの修正作業をしていて、それをコミットしてしばらくコンテナを放置していました。
2~3日経ってから再びアプリの修正をしようとブラウザでlocalhostにアクセスしました。
このlocalhostにはDjangoの開発用サーバーが繋がっているはずなので、ブラウザでアクセスしたら画面にはアプリの画面が表示されるはずでした。
しかし、ブラウザでアクセスしても一向に画面が表示されません。
Chromeブラウザでアクセスしていたのですが、タブのアイコンがくるくる回るだけでページは真っ白なままです。
つい最近まで何の問題もなく使えていたのに、いったいどうして?
私はこの問題に取り組まざるを得なくなりました。
(^ _ ^) | やってやるぜ |
原因はDocker?
私の開発用PCはWindowsを使っています。
DockerもWindows用のDockerです。
最初、私はDockerの不具合を疑いました。
そこでDockerを再起動したり、コンテナを削除して再度コンテナを走らせたりをしました。
さらにDockerのバージョンを更新して、最新の状態で使うようにもしました。
しかし、相変わらず画面がつながりません。
これはWindows版のDockerのバグかもしれない、という考えが頭によぎりましたが、それは最終終着駅だと思い直し、他にも色々試してみることにしました。
ポートが間違っている?
実行しているDjangoのコマンドは↓です。
python manage.py runserver 0.0.0.0:80
コンテナ内では↑のコマンドを実行していました。
コンテナはポートフォワーディングでホストのポート7777
にコンテナのポート80
が繋がっている状態です。
このフォワーディングでは↑のコマンドを実行した後に、ブラウザでhttp://localhost:7777
にアクセスすれば繋がるはずです。
しかし、繋がらないのでポートが間違っているのかな? と疑うようになりました。
そこでrunserver
に指定するポートを変えてみたりしましたが、結果は同じでした。
アドレスが間違っている?
localhost
が間違っているのでは? と疑うようにもなった私は、アドレスを変えてみたりもしました。
Windowsのipconfig
コマンドで表示されるIPアドレスをブラウザのアドレスバーに貼り付け、ポートを指定してアクセスしたりもしましたが、やはり結果は同じです。
さらには関係のないWSL2のIPアドレスも試してみました。
これはWSL2の環境ではip route
というコマンドを実行するとWSL2のIPアドレスが表示されるので、これをブラウザに貼り付けたりもしました。
しかし、当然ですが今回はWSL2は関係ないので結果は変わりません。
アドレスもポートも間違っていないなら、なにか他の原因があるということか・・・。
私の推理は一歩進みました。
ポートが使用中?
別のアプリがrunserver
と同じポートを使っていて、接続がコリジョンしているのではないか?
という案が出ました。
そこでプロセスを確認して見ることにしました。
Windowsの端末で以下のコマンドを実行します。
netstat -oan
するとポートを使っているプロセスのプロセスIDが表示されます。
このコマンドでポート7777
を使っているプロセスを調べて、このプロセスをkill
することにしました。
Windowsでプロセスをkill
するには↓のコマンドを使います。
taskkill /pid プロセスID
このコマンドは管理者権限で立ち上げた端末で実行する必要があります。
↑のコマンドでプロセスをkill
してみましたが、やはり結果は同じでした。
Pythonの組み込みサーバーを起動する
Djangoとは別に、Pythonには組み込みサーバーがあります。
これは↓のコマンドで起動できます。
python -m http.server
オプション-m
はモジュールをコマンドとして実行するオプションです。
↑の場合はhttp.server
というモジュールをコマンドとして実行しています。
さらにポートを80
に指定するには↓のようにコマンドを打ちます。
python -m http.server 80
↑のコマンドを実行すると、コンテナのポート80
に組み込みサーバーが公開されます。
この状態でブラウザを確認してみると、なんとちゃんと画面が表示されていました。
画面と言っても、出力されているのはアプリの画面ではなく、http.server
が配信する画面です。
これは現在のディレクトリを基準としたインデックスです。
Pythonの組み込みサーバーでは表示されるということは、どうやらDockerには問題がないということがわかりました。
原因はrunserver
, つまりmanage.py
にありそうです。
プロジェクトが壊れている?
私はコンテナ内の開発中のプロジェクトとは別のディレクトリにdjango-admin startproject
で新しいDjangoプロジェクトを作成しました。
そしてそのプロジェクトに移動して、python manage.py runserver 0.0.0.0:80
を実行してみました。
するとなんと、ブラウザにはちゃんとDjangoのページが表示されています。
これはプロジェクトを作成直後のDjangoのウェルカムページです。
この時の私にはこのページがまぶしく見えました。
この調査でわかったのは、どうやらDockerには問題はなく、Djangoのrunserverにも問題はない。
原因は、開発中のプロジェクトのmanage.py
にある、ということでした。
私は開発中のプロジェクトの破損を疑いました。
しかし、プロジェクトはGitで管理していますが、それらしいファイルの破損はありません。
まさかGitも壊れているのか? と疑うようにもなりましたが、とりあえずそれは置いておきました。
開発中のプロジェクトのmanage.py
は内部でプロジェクトのsettings.py
を読み込んでいます。
ということはこのsettings.py
に問題がある可能性が高い、ということで私はデバッグを行うことにしました。
settings.py
に書いてある独自の定義をコメントアウトしていき、作成したアプリのアンインストール(INSTALLED_APPS
からの除外)も行いました。
このようなデバッグは、アプリが複雑に絡み合っているプロジェクトにおいてほとんど無意味です。
なぜならエラーが頻発するからです。
しかし、この時の私はこの方法以外に他にやることがありませんでした。
当然ながら、このようなデバッグを行ったところ、画面にはDjangoのエラー画面が表示されました。
エラー画面が・・・・・・。え? エラー画面?
あれぇ? 画面が表示されてるじゃん!
settings.pyの読み込みはOK?
なんと画面には、あれだけなにをしても何も表示されなかったのに、Djangoのエラー画面が表示されています。
私は思わず椅子から立ち上がり、そしてすぐに座り直しました。
ということはmanage.py
はsettings.py
の読み込みは行っているということになります。
このことからわかるのは、どうやらアプリ部分のコードがあやしいということになります。
私はデバッグを続けることにしました。
具体的には表示されているエラーを除外していきます。
このエラーは、settings.py
でアプリをアンインストールしたことに起因するエラーです。
つまり、アンインストールされているアプリが、プロジェクト内で参照されている(インポートなど)というものです。
このエラーをすべて取り除いていけば、最終的に動作する最小形態のプロジェクトを得られることになります。
私はデバッグを続け、エラーを取り除いていきました。
すると、urls.py
のデバッグで、あるルート情報をコメントアウトすると画面が表示され、コメントアウトを戻すと画面が再びビジーになることがわかりました。
どうやらこのルート情報からつながる処理にビジーの原因があることがわかりました。
ビジーの原因はだれ?
私はルート情報からビュー、テンプレートとデバッグを続けました。
するとあるテンプレートファイル内の行を取り除くとビジーが無くなることがわかりました。
そのテンプレートファイルの行は↓のようなものでした。
{% render_bundle 'main' 'js' 'CORE' %}
render_bundle
というタグはdjango-webpack-loader
で追加されるタグです。
開発中のプロジェクトはSPAも扱っていて、そのSPAの開発にWebpackを使っていました。
そのため↑のようにrender_bundle
でWebpackが生成するファイルを描画していたのです。
この行を取り除くと、ビジーがなくなりました。
どうやら原因はこのrender_bundle
にあることがわかりました。
この時、私はすぐにピンときました。
render_bundle
がビジーになるのは、描画するファイルがないからだ!
私はすぐにそう判断し、Webpackのディレクトリに移動しました。
原因はWebpack関連だった
私はnpm
とWebpackを使ってすぐにソースコードのビルドを行いました。
具体的には↓のコマンドを実行します。
npm run build
build
コマンドはpackage.json
には↓のように書かれています。
{ "scripts": { "build": "webpack", }, }
このコマンドを実行するとJavaScriptのソースコードがビルドされ、ディレクトリにファイルが配置されました。
するとビンゴ! 画面のビジーが無くなり懐かしのアプリの動作画面が表示されました。
おわりに
今回のDjangoのrunserver
が繋がらない原因ですが、結果的にrunserver
は繋がっていたが、コンテンツの描画でビジーになっていたという結果になりました。
画面が表示されていなかったのでてっきりrunserver
の不具合を疑うことになりましたが、結果は違いました。
こういったエラーで一番最初に疑うべきなのは開発者のオリジナルのコンテンツの部分だと、あらためて思い知らされました。
私はDockerもDjangoもWSL2も疑ってしまった罪深き開発者です。
どうかお許しください。
(^ _ ^) | ラーメン |
(・ v ・) | タンメン |