はじめに
大高隆・著「動かして学ぶ!Python Django開発入門」を使用して
python・Djangoの学習を始めた初学者です。
ruby・railsを使用して4ヶ月ほどプログラミングの勉強をしていましたが、
エンジニア転職にあたり、pythonを使用することになったのでこの本を片手に勉強を始めました。
ド級の素人なので、補足・ご指摘等コメントいただけると大変助かります。
概要
いよいよアプリをデプロイ目前。
その前に、nginx✖️djangoの接続を勉強するため、
ローカル環境でセットアップを試してみました。
初心者の自分には断片的であったり問題解決につながる記事が少なかったので、
自分用メモとして記事を残しておきます。
やり方としては下記の公式ドキュメントに沿って行いました。
ドキュメントに沿って詰まった点の補足を自分に向けてコメントします。
Setting up Django and your web server with uWSGI and nginx
※この先登場する文章中のリンクについては、全てこのドキュメント内の該当箇所になります。
環境
- python3.8.2
- django3.0.7
- uWSGI2.0.19.1
- nginx1.19.3
- macOS Catalina10.15.6
やりたいこと
クライアント ⇄ webサーバ(nginx) ⇄ APサーバ(uWSGI) ⇄ Djangoアプリ
の流れを作りたい。
使用しているものについては、なんとなくの理解の部分が多いので、
別途参考記事をみて理解いただくのが最善かと思います。
・nginx・uWSGIについての参考記事
djangoでのプロジェクト作成方法等もここでは端折ります。
わからない場合はこのあたりに書いてあります。
ディレクトリ構成
※一部省略しています。
|--app1
|--app2
|--config(設定などなど)
| |--settings
| | |--base.py(開発・本番環境共通項目のsettings)
| | |--local.py(開発環境用のsettings)
| | └--production.py(本番環境用ののsettings)
| |--project_uwsgi.ini(チュートリアル中に作成)
| |--urls.py
| └--wsgi.py
|--static
|--manage.py
|--test.py(クライアント⇄uwsgi⇄python確認用)
└--uwsgi_params(チュートリアル中に作成)
ポイント1
test.py を実行して、
クライアント ⇄ uWSGI ⇄ Python
の流れの確認まではすんなり.
そのあと、クライアント ⇄ uWSGI ⇄ Djangoの指定コードでは、
uwsgi --http :8000 --module mysite.wsgi
となっています。これを上記のディレクトリ構成に合わせると、
uwsgi --http :8000 --module config.wsgi
ちなみに指定している"wsgi.py"の中身ですが、まだ本番環境周りについては何も記述していないので、
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.local')
としてエラーが出ない様に一旦"local.py"の方が読み込まれる様に便宜的にしています。
これで、クライアント ⇄ uWSGI ⇄ Djangoの流れが確認できました。
ポイント2
nginxのインストールについて、自分はインストール済でしたが一応。
ドキュメント上だと、
sudo apt-get install nginx
sudo /etc/init.d/nginx start
となっていますが、自分は
brew install nginx
で入れておりました。問題なくいけました。
ポイント3
uWSGIのおまじないファイルを作成します。(この辺りです。)
中身については、思考停止で構わない様なので、完全にコピペです。
プロジェクト直下のuwsgi_paramsです。
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
もう一つnginxについてのファイルを作成します。
This conf file tells nginx to serve up media and static files from the filesystem, as well as handle requests that require Django’s intervention. For a large deployment it is considered good practice to let one server handle static/media files, and another handle Django applications, but for now, this will do just fine.
ディレクトリはドキュメントの仰せの通りに、
**/usr/local/etc/nginx/sites-available/**内に作成しました。
# the upstream component nginx needs to connect to
upstream django {
server unix:///Users/name/projects/project/project.sock;
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name 127.0.0.1;
charset utf-8;
# max upload size
client_max_body_size 75M;
# 作成しているアプリの構成上、mediaは不要なので、
ここでは割愛しています。
location /static {
alias /Users/name/projects/project/static;
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /Users/name/projects/project/uwsgi_params;
}
}
からの
sudo ln -s /usr/local/etc/nginx/sites-available/project_nginx.conf /usr/local/etc/nginx/sites-enabled/
を実行。"site-enabled"がない場合は作成しておきましょう。
ポイント4
Deploying static files
Before running nginx, you have to collect all Django static files in the static folder. First of all you have to edit mysite/settings.py adding:
ということで、djangoアプリの静的ファイルを集める必要がある様です。
なぜかはよくわかりません。あとで調べてみます。
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
をsetteingsに追加して、
python manage.py collectstatic
を実行。
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
の記述を元からしてあったので、同じ様なもん出し、書かなくてもええやろ
と思っていましたが、ないとエラーになってしまいました。
そして、nginxを再起動。
sudo nginx -s stop
sudo nginx
これで
uwsgi --socket project.sock --wsgi-file test.py
を実行して、パスにアクセスして[HelloWorld]が表示されれば、
クライアント ⇄ nginx ⇄ uWSGI ⇄ Python
ができているという確認ができるよ、ということの様です。なるほど。
ちな、上記でエラーが出る時は、
--chmod-socket=666や**--chmod-socket=664**をつけて実行してみるとうまくいくかもと。
なるほど。
さらにさらに、
uwsgi --socket project.sock --module config.wsgi --chmod-socket=666
としてあげれば、ついに
クライアント ⇄ nginx ⇄ uWSGI ⇄ djangoの完成ですね。
最後に、"project_uwsgi.ini"を作成してあげることで、管理がしやすくなるということでconfig内に作成。
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /Users/name/projects/project
# Django's wsgi file
module = config.wsgi
# the virtualenv (full path)
home = /Users/name/projects/project/venv/
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = /Users/name/projects/project/project.sock
# ... with appropriate permissions - may be needed
# chmod-socket = 666
# clear environment on exit
vacuum = true
こうすることで、
uwsgi --ini project_uwsgi.ini
とすると、先ほどと同じ様にDjangoアプリを起動することができました。
追記
そういえば、エラーが二つほど。
①nginxの502エラー
↓
uwsgi --ini project_uwsgi.ini --chmod-socket=666
これでうまく起動してくれました。
②[error] 52089#0: *24 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, client: 127.0.0.1, server: ※※※.※※※.※※.※, request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:8001", host: "127.0.0.1:8000"
↓
nginxが起動していないだけだった。
ターミナルで"sudo nginx"で解決。
まとめ
環境を作るって、難しい。