MS AzureのLinux VMでhttps+Django+Nginx+uWSGI

Microsoft Azureの仮想マシン上でdjangoのサイトを構築する際、
sslに対応させるための情報が古いものばかりだったので記しておきます。

## 環境
Microsoft Azure Virtual Machine
ubuntu 18.04 Server
Nginx 1.14.0
uWSGI 2.0.17.1 (64bit)
Let's Encrypt
Python 3.6.7
django 2.1.5

## インストール

```python
# apt install python3-dev libpcre3 libpcre3-dev
# apt install nginx certbot python3-certbot-nginx uwsgi uwsgi-plugin-python3
```

## 証明書
AzureではLet's Encryptは使えないという情報が多く、自己署名証明書でいこうとしていましたが
成功したという事例もあるようなので使ってみました。

```bash
# certbot -d ooo.xxx.cloudapp.azure.com --nginx
```

1.メールアドレスを入力
2.利用規約への同意
3.メールアドレスをElectronic Frontier Foundationへ共有して良いか否か、
4.httpをhttpsにリダイレクトするか否か

の情報を入力します。

あとは自動でしてくれる。なんて便利な世の中。

## nginxの設定

djangoプロジェクトとともにgit管理しようと思いますので
djangoのプロジェクトディレクトリ直下に入れたmy_nginx.confを編集。

```bash:my_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
	# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
	server 127.0.0.1:8001; # for a web port socket (we will use this first)
}

server {
        server_name ooo.xxx.cloudapp.azure.com; # managed by Certbot
	charset	utf-8;

	location /static {
		alias /path/to/your/django/static;
	}

	location / {
		uwsgi_pass	django;
		include		/path/to/your/django/project/uwsgi_params;
	}
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/rooo.xxx.cloudapp.azure.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ooo.xxx..cloudapp.azure.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

}

server {
        if ($host = ooo.xxx.cloudapp.azure.com) {
            return 301 https://$host$request_uri;
        }
	listen 80 ;
	listen [::]:80 ;
        server_name ooo.xxx.cloudapp.azure.com;
        return 404; # managed by Certbot
}
```

そしてmy_nginx.confに対してシンボリックリンクを貼っておきます。

```
# ln -s /etc/nginx/sites-enabled/my_nginx.conf /path/to/my_nginx.conf
```

## uWSGIの設定ファイル

djangoのプロジェクトディレクトリ直下にuwsgi_paramsというファイルを設置

```: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;
```
これは基本的にいじる必要はない。
そしてmy_uwsgi.iniをdjangoのプロジェクト直下（場所はどこでもいい）におく

```:my_uwsgi.ini
[uwsgi]
uid = nginx-user
gid = nginx-user
chdir = /path/to/your/django/project/directory
module = project_name.wsgi
home = /path/to/your/venv/directory
plugins = python3

master = true
socket = 127.0.0.1:8001
```
（/path/to/your/django/project/directory/project_name/wsgi.pyがあるという仮定）

そして次を実行

```
$ uwsgi --ini /path/to/your/my_uwsgi.ini --enable-threads
```

たぶんこれでいける。
今回の設定では
443ポートを受信できるようにしておけば、
1. 443からnginxがリクエストを受け取る
2. 8001で待機しているuWSGIに丸投げ
3. djangoで処理
という流れになる。djangoは起動させておく必要はない。

uwsgiを自動起動させる場合は/etc/systemd/system/uwsgi.serviceを作成する

```sh:uwsgi.service
[Unit]
Description = uwsgi service

[Service]
Restart = always
ExecStart = /usr/bin/uwsgi --ini=/home/tfukuda/www/RefugeButtonServer/myuwsgi.ini
ExecReload = /bin/kill -s HUP ${MAINPID}
KillSignal = SIGQUIT

[Install]
WantedBy = multi-user.target
```

そして登録。

```sh
#systemctl enable uwsgi.service
```

これで

```sh
#systemctl stop uwsgi.service
#systemctl start uwsgi.service
```
などが可能。