はじめに
Docker環境でDjangoアプリにブラウザからアクセスできない場合、考えられる原因とその切り分け方法を詳しく解説します。
個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。
発生していたエラー
- ブラウザから
http://<サーバーのIP>:8000
へアクセスできない -
curl
コマンドで確認するとConnection refused
やTimeout
エラーが発生 -
docker logs django-dev
を確認するとListening at: http://127.0.0.1:8000
と表示されている -
netstat
コマンドでポート8000がリッスンされていない -
ufw
やiptables
によるブロックの可能性あり
チェックリスト
チェック項目 | 確認方法 | 解決策 |
---|---|---|
ポートが公開されているか |
docker ps でポート 8000 の公開状態を確認 |
docker-compose.yml に ports: "8000:8000" を追加し、コンテナを再起動 |
Djangoが 0.0.0.0 でリッスンしているか |
docker logs django-dev で Listening at: http://127.0.0.1:8000 になっていないか確認 |
manage.py runserver 0.0.0.0:8000 で起動 |
ALLOWED_HOSTS の設定ミス |
settings.py の ALLOWED_HOSTS を確認 |
ALLOWED_HOSTS = ["your-server-ip", "localhost"] に変更 |
ファイアウォールの設定を確認 | `sudo netstat -tulnp | grep 8000` でポートが開いているか確認 |
Nginx の設定ミス |
/etc/nginx/nginx.conf の proxy_pass を確認 |
proxy_pass http://django-dev:8000; の設定を修正し、Nginx を再起動 |
書こうと思ったきっかけ
この問題は、DockerでDjangoアプリを動作させる際によく発生するため、その切り分け手順をまとめることでスムーズにトラブルシューティングできるようにしたかったため。
1. コンテナのポートが正しく公開されているか確認
まず、Dockerのポートマッピングが正しく設定されているか確認しましょう。
確認方法
以下のコマンドを実行し、ポート設定を確認します。
docker ps
出力例:
CONTAINER ID IMAGE COMMAND PORTS NAMES
123456789abc django-app "gunicorn --bind 0.…" 0.0.0.0:8000->8000/tcp django-dev
0.0.0.0:8000->8000/tcp
になっていれば正しく公開されています。
0.0.0.0:8000
が表示されていない場合、 docker-compose.yml
に以下の ports:
設定を追加してください。
services:
django-dev:
ports:
- "8000:8000"
この変更後、以下のコマンドでコンテナを再起動します。
docker-compose up -d --force-recreate
2. Djangoが 0.0.0.0
でリッスンしているか確認
Djangoはデフォルトで 127.0.0.1
で動作するため、コンテナの外部からアクセスできません。
確認方法
docker logs django-dev
出力例:
django-dev | [INFO] Listening at: http://127.0.0.1:8000 (1)
127.0.0.1
でリッスンしている場合、0.0.0.0
に変更する必要があります。
解決策
manage.py runserver
のオプションを修正:
python manage.py runserver 0.0.0.0:8000
または、gunicorn
の設定を変更:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
3. ALLOWED_HOSTS
の設定ミス
Djangoの settings.py
に適切な ALLOWED_HOSTS
を設定していないとアクセスがブロックされます。
確認方法
settings.py
に以下のような設定があるか確認してください。
ALLOWED_HOSTS = ["*"]
セキュリティ的に "*"
は非推奨なので、必要なホストのみ指定するのがベストです。
ALLOWED_HOSTS = ["your-server-ip", "localhost"]
4. ファイアウォールの設定
Linuxのファイアウォール (ufw
など) が 8000
ポートをブロックしている可能性があります。
確認方法
sudo netstat -tulnp | grep 8000
または
sudo ss -tulnp | grep 8000
ポート開放のコマンド:
sudo ufw allow 8000/tcp
sudo systemctl restart ufw
また、クラウド環境(AWS、GCPなど)を使用している場合は、セキュリティグループの設定 でポート 8000
を開放する必要があります。
5. Nginx の設定ミス
Djangoを gunicorn
+ nginx
で動作させている場合、proxy_pass
の設定ミスが原因でアクセスできない可能性があります。
確認方法
Nginxの設定ファイル (/etc/nginx/sites-available/default
または nginx.conf
) に以下のような設定があるか確認します。
server {
listen 80;
server_name your-server-ip;
location / {
proxy_pass http://django-dev:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Nginx をリスタート
sudo systemctl restart nginx
まとめ
この問題は、ポートの公開設定、Djangoのリスニングアドレス、ALLOWED_HOSTS
、ファイアウォール設定、Nginxの設定ミスなど複数の要因によって発生する可能性があります。
チェックリストを活用し、段階的にトラブルシューティングを進めてください。
まずは docker ps
でポートが 0.0.0.0:8000
になっているか確認し、それでもダメなら docker logs django-dev
のエラーメッセージを確認し、ファイアウォールや Nginx の設定を見直してみてください。