djangoをXserver にデプロイできない!500 Internal Server Errorの対処法7選
djangoを使ってWebアプリを開発したら、次は公開することが目標ですよね。
しかし、Xserverにデプロイしようとしたら、500 Internal Server Errorというエラーが出てしまい、途方にくれている方もいらっしゃるかもしれません。
500 Internal Server Errorとは、サーバー側で何らかの問題が発生して、リクエストを処理できなかったことを示すエラーコードです。原因はさまざまですが、djangoの設定やパーミッション、モジュールのインストールなどが考えられます。
この記事では、私がdjangoをXserverにデプロイした際に500 Internal Server Errorが出た時の試行錯誤を記録するとともに解決策を紹介します。
最後に上手くいったファイルの中身を載せています。
私の環境
私の場合は以下の環境でエラーが出ていました。
- Xserver
- Python 3.8.13
- Django==4.1
- miniconda(django-env)
- サブドメイン使用
フォルダの構成は以下の通りです。
home
│
└─xs000000 (000000は人によります)
└─hogehoge.com
└─public_html
└─app.hogehoge.com
├─Templates
├─config
├─app
├.htaccess
├index.cgi
├manage.py
対処法1:ファイルのパーミッションを変更する
ファイルのパーミッションを適切に設定しないとエラーが出ます。
適切なパーミッションは以下の通りです。
index.cgi
-> 755.htaccess
-> 644
パーミッションを変更するのはSSH接続してindex.cgi
があるフォルダまで移動し、以下のコマンドを入力してください。
chmod 755 index.cgi
chmod 644 .htaccess
または、ファイルマネージャーからパーミッションを変更してください。
ファイルマネージャーには、Xserverにログイン後、「ファイル管理」をクリックして入ることができます。
対処法2:numpy, Matplotlibを使えるようにする
numpy, Matplotlibをそもそも使っていないという方は読み飛ばしてください。(依存関係で使われている可能性もあるので試してみてもいいかもです。)
Xserver上でのマルチスレッドの制約により、numpyがマルチスレッドを使用することが制限されることが原因のようです。
そこでindex.cgi
に以下のコードを追加します。
os.environ['OPENBLAS_NUM_THREADS'] = "1"
全体のindex.cgi
はこちらです。
#!/home/xs000000/miniconda3/envs/django-env/bin/python
# coding: utf-8
import sys, os
sys.path.insert(0, '/home/xs000000/miniconda3/envs/django-env/bin')
os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings'
os.environ['OPENBLAS_NUM_THREADS'] = "1" # このコードを追加
from wsgiref.handlers import CGIHandler
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
CGIHandler().run(application)
対処法3:SSH接続した上でpython manage.py runserverを実行する
次に試してみてほしいのはSSH接続してから以下のコマンドをmanage.pyの階層で実行することです。
python manage.py runserver
実行してアプリを立ち上げることができた方は次に行ってください。エラーの原因はやはりindex.cgi, .htaccessにあると思われます。
一方で実行時にエラーが出た場合は、そのエラー内容に従って解決しましょう。
コメントに環境とエラーの内容のコピー、試行錯誤状況を書いていただければ対処できそうなものはします。
対処法4:プログラム内の改行のコードを変更する
WindowsとUnix/Linux系のシステムでは、改行コードの表記方法が異なるため、互換性の問題が生じることがあります。
フォルダをそのままコピペしてXserverに置くと改行コードが適切でない場合があります。私がそうでした。
私は、vscodeで改行コードを変更しました。
vscodeの右下を見てみると上のような感じのものがあると思います。
すべてのファイルを「CRLF」の部分を押して「LF」に変更してください。
これで解決する方もいらっしゃると思います。
対処法5:キャッシュをクリアする
キャッシュをクリアしましょう。
PC内に残っているキャッシュが悪さをしている場合があります。
対処法6:SSH接続を切ってみる
SSH接続していると500 Internal Server Error
が出ることがあります。
ですので、SSH接続を切ってから時間をおいてサイトを開いて見てください。
時間を空けることが大切です。意外と時間が解決することがあります。
対処法7:index.cgiではなくindex.fcgiに変更する
index.cgi
をやめてindex.fcgi
にしましょう。
正直なところ理由は分かりませんが、私はこれで解決しました。以下、私の場合のファイルの中身です。
index.fcgi
#!/home/xs000000/miniconda3/envs/django-env/bin/python
# coding: utf-8
import sys, os
sys.path.insert(0, '/home/xs000000/miniconda3/envs/django-env/bin')
os.environ['DJANGO_SETTINGS_MODULE'] = 'config.settings'
from flup.server.fcgi import WSGIServer
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
WSGIServer(application).run()
他の記事の方などを見て頂けると分かると思いますが、4行目の部分は私と同じように書かれている方やsys.path.append("/home/[サーバーのID]/[独自ドメインの名前]/public_html/[Projectの名前]/")
のように書かれている方がいます。
どこまで影響があるのか分かりませんが、私はこの書き方ではなく、sys.path.insert(0, '/home/xs000000/miniconda3/envs/django-env/bin')
で正常に動作しています。
.htaccess
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]
HTTPSへのリダイレクトのコードとindex.fcgi
に転送するためのコードが含まれています。
エラーの解決には最後の行が大切です。
他の方の.htaccess
を見ると以下のようなパターンが多いようです。
RewriteRule ^(.*)$ /index.fcgi/$1 [QSA,L]
RewriteRule ^(.*)$ /app.hogehoge.com/index.fcgi/$1 [QSA,L]
ですが、RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]
で試してみることをお勧めします。
変更した後はSSH接続を切ってキャッシュもクリアしてしばらくしてからサイトを表示してみましょう。
コメント