Python実行サーバ構築（Python+uWSGI+Django+Nginx）

# 概要
> Python + uWSGI + Django + Nginx な環境を構築してみる。
> 今更感もあるし、そもそも他の Qiita 記事を参照して作業をしているので、わざわざ記事にする必要があるのか？という疑問もあるにはあるが、まぁ、備忘録として残しておく。


## 環境
|環境|URL|
|:--|:--|
|AWS|https://〜/hello/|

## 横展開
サイト（アプリ）を増やしたい場合は、以下作業を実施する。

- プロジェクトとアプリを Django で作成する
- 増やすサイト用の nginx.conf、ini ファイル、service ファイルを作成する
- サービスを起動する

---
# 手順

## １）ディレクトリ作成
```sh
mkdir -p /WORK/etc;
mkdir -p /WORK/var/www;
mkdir -p /WORK/var/log;
mkdir -p /WORK/var/tmp;
mkdir /etc/nginx/sites-available;
mkdir /etc/nginx/sites-enabled;
```

## ２）設定ファイル作成

### Nginx 設定
```config:/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    #-- WORK
    include /etc/nginx/sites-enabled/*.conf;
}
```
```config:/WORK/etc/nginx_myweb.conf
upstream django {
    server 127.0.0.1:8001;
}
server {
    #-- SSL
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    server_name  WORK.work;
    ssl_certificate     "/etc/letsencrypt/live/WORK.work/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/WORK.work/privkey.pem";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    charset utf-8;
    client_max_body_size 75M;

    #-- myweb
    location /static {
        alias /WORK/var/www/myweb/static;
    }
    location / {
        uwsgi_pass  django;
        include     /WORK/var/www/myweb/uwsgi_params;
    }
}
```

### UWSGI 設定
```config:/WORK/etc/myweb.ini
[uwsgi]
master = true
socket = :8001
module = myweb.wsgi
pythonpath = /WORK/var/www/myweb
logto = /WORK/var/log/uwsgi.log
pidfile = /WORK/var/tmp/uwsgi.pid
```

### サービス設定
```config:/WORK/etc/myweb.service
[Unit]
Description = myweb
After = syslog.target
[Service]
ExecStart = /usr/bin/uwsgi --ini /WORK/etc/myweb.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
```

## ３）プロジェクトとアプリの生成
> Django でプロジェクトとアプリを生成する

```sh:プロジェクト生成
cd /WORK/var/www;
django-admin startproject myweb;
```
```sh:アプリ生成
cd /WORK/var/www/myweb;
python manage.py startapp hello;
```

## ４）アプリ設定
```python:/WORK/var/www/myweb/myweb/settings.py
INSTALLED_APPS = [
    ＜省略＞
    'hello', ← 追加
]
＜文末>
STATIC_ROOT = os.path.join(BASE_DIR, "static/") ← 追加
```
```python:/WORK/var/www/myweb/hello/views.py
# Create your views here.
↑ここから下に追加 ↓↓↓
from django.http import HttpResponse
＜空行＞
def main(request):
    return HttpResponse("Hello!")
```
```python:/WORK/var/www/myweb/myweb/urls.py
import hello.views       ← 追加
from hello import views  ← 追加
＜空行＞
urlpatterns = [
    ＜省略＞
    url(r'^hello/', hello.views.main),  ← 追加
]
```

## ５）マイグレーション
```sh
python manage.py migrate;
python manage.py collectstatic;
```

## ６）サービス起動（デプロイ）
```sh:Nginx
ln -s /WORK/etc/nginx_myweb.conf /etc/nginx/sites-enabled/.;
systemctl status nginx;
systemctl start nginx;
systemctl stop nginx;
systemctl start nginx;
systemctl status nginx;
```
```sh:uWSGI
ln -s /WORK/etc/myweb.service /etc/systemd/system/myweb.service;
systemctl status myweb;
systemctl start myweb;
systemctl stop myweb;
systemctl start myweb;
systemctl status myweb;
```

## ７）アプリ変更をした場合
- ５のマイグレーションを実施する（`python manage.py migrate;`）
- ６の uWSGI のりスタートを実施する（`systemctl restart myweb;`）