ConoHa VPSにDjango環境構築&Gunicorn, Nginxの設定

# ConoHa(Ubuntu18.04)にDjango環境を構築する
Miniconda3、venvを使う方法を解説します。

# Miniconda3で環境構築

## インストール
ローカルのマシンで[公式サイト](https://conda.io/miniconda.html)からインストーラをダウンロードする。
`Miniconda3-latest-Linux-x86_64.sh`のようなファイルがダウンロードされる。

このファイルを`scp`コマンドでVPS側へ送る。

```
$ scp ~/Miniconda3-latest-Linux-x86_64.sh conoha:~
```

VPS側へ送れたことをSSH接続して確認する。

```
$ ls
$ Miniconda3-latest-Linux-x86_64.sh
```

インストールする。

```
$ bash Miniconda3-latest-Linux-x86_64.sh
```

ライセンスに同意し、パスを通すか確認されるので`yes`を叩く。

### 手動でMiniconda3のパスを通す

1. 現段階で動いているPythonの情報を確認する。
シェルで`python`と叩けば実行されているバージョンなどがわかる。Miniconda(Anaconda)の`Python`が実行されていれば`Python`のバージョンの下に`Anaconda`と表示される。

1. シェルで`which python`と叩けば、パスが通っている`Python`がわかる。

1. `.bashrc`や`.zshrc`に以下を追記。

```~/.zshrc
# Miniconda3
export PATH="/home/ユーザ名/miniconda3/bin:$PATH"
```

反映させる

```
$ source ~/.zshrc
```

## Django用の環境を作る
シェルでDjango用の環境(mydjango)を作成し、有効化する。
(Pythonのバージョン指定は`python=3.7.3`とすればいい)

```
# 環境作成
$ conda create -n mydjango

# 有効化
$ conda activate mydjango

# 無効化
$ conda deactivate
```
## Djangoをインストール
AnacondaやMinicondaでのパッケージ管理には`conda`を使うのが一般的（？）とされてますが、ここでは`pip`を使います。

```
# アップグレードを行う
$ pip install --upgrade pip
$ pip install django
```
# venvで環境構築
仮想環境を作りたいディレクトリに移動しておいてください。
ここでは、ホームディレクトリに`django`というフォルダをつくりその中に`myvenv`という名前の仮想環境を置くことにします。

```
$ cd ~
$ mkdir django && cd django

# 仮想環境作成
$ python3 -m venv myvenv

# もしエラーがでたら以下を実行
$ sudo apt install python3-venv

# 仮想環境切り替え
$ source myvenv/bin/activate
## virtualenv が起動すると、プロンプトの行頭に(myvenv)が現れる。
## 環境から抜けるときは deactivate を実行

# ライブラリのインストール
$ pip install --upgrade pip
$ pip install django

# pipエラーが出たら以下を実行
$ python3 -m pip install --upgrade pip
```


# NginxとGunicornのインストール
役割のイメージはこんなかんじ。
クライアント <--> Internet <--> Nginx <--> Gunicorn

Gunicornなどのアプリケーションサーバ単体でも動作するが、Nginxをフロントに置いてリバースプロキシとして動作させることで、負荷分散やセキュリティ強化、静的ファイル処理の高速化が図れる。
また、GunicornはNginxと組み合わせて動かすことを推奨している。

## Nginxのインストール

```
# Nginxをインストール
$ apt install nginx
```

## Gunicornのインストール

```
# Gunicornのインストール
$ pip install gunicorn
```

# NginxとGunicornの設定について
## Nginxの設定
Nginxのsites-availbleにDjangoアプリ用の設定ファイル(ここでは`project`)を作成する

```
$ vim /etc/nginx/sites-available/project
```

```/etc/nginx/sites-available/project
upstream app_server{
    server 127.0.0.1:8000 fail_timeout=0;
}
server{
    listen 80;
    server_name IPAdress or dmain;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
            root /home/ ubuntu / myprojectdir; #プロジェクトフォルダ
    }
    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn/socket;
    }
}
```

Nginxのsites-enabledに作成した設定ファイルへのシンボリックリンクを作成

```
$ sudo -ln -s /etc/nginx/sites-available/project /etc/nginx/sites-enabled

# 構文チェック
$sudo nginx -t
```
チェックをパスしたらNginxを再起動してファイアウォールの設定を変更。

```
$ sudo systemctl restart nginx
$ sudo ufw allow 'Nginx Full'
```
#### ディレクトリ構成（参考）
```
/etc/nginx
|--conf.d
|--fastcgi.conf
|--fastcgi_params
|--koi-utf
|--koi-win
|--mime.types
|--modules-available
|--modules-enabled
|  |--50-mod-http-geoip.conf
|  |--50-mod-http-image-filter.conf
|  |--50-mod-http-xslt-filter.conf
|  |--50-mod-mail.conf
|  |--50-mod-stream.conf
|--nginx.conf
|--nginx_temp.conf
|--proxy_params
|--scgi_params
|--sites-available
|  |--default
|  |--project
|--sites-enabled
|  |--default
|  |--project
|--snippets
|  |--fastcgi-php.conf
|  |--snakeoil.conf
|--uwsgi_params
|--win-utf
```

## Gunicornの設定
- [この記事](https://qiita.com/mono11/items/a0a0996f80d86bd7a68c)に書いてあるのとほとんど同じ内容

### Gunicorn用のsystemdソケットファイルを作成する

`sudo`権限でGunicorn用のsystemdソケットファイルを作成する

```
$ sudo vim /etc/systemd/system/gunicorn.socket
```

```/etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn/socket

[Install]
WantedBy=sockets.target
```

### Gunicorn用のsystemdサービスファイルを`sudo`権限で作成する。
このとき、**サービスのファイル名は拡張子を除いてソケットのファイル名と一致する必要がある。**

- プロセスはすべての関連ファイルを所有しているため、プロセスの所有権を通常ユーザーアカウントに与える。
- NginxがGunicornと簡単に通信ができるように`www-data`グループにグループの所有権を与える。
- ユーザ名を仮に`ubuntu`としている

```
$ sudo vim /etc/systemd/system/gunicorn.service
```

※`ExecStart=/home/ ubuntu / myprojectdir /bin/gunicorn`の`/home/ ubuntu / myprojectdir /bin/gunicorn`は`which gunicorn`で表示されたパスにする。

```/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ ubuntu / myprojectdir
ExecStart=/home/ ubuntu / myprojectdir /bin/gunicorn -- access-logfile - -- workers 3 --bind unix:/run/gunicorn/socket myproject.wsgi

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

## Gunicornソケットを起動して有効化する
これにより、起動時に`/run/gunicorn/socket`ファイルが作成される。そのソケットに接続するとsystemdはそれを処理するために`gunicorn.service`を自動的に起動する。

```
$ sudo systemctl start gunicorn.socket
$ sudo systemctl enable gunicorn.socket
```

プロセスが開始できたかどうかを確認する。

```
$ sudo systemctl status gunicorn.socket
```

# 参考
- [EC2のUbuntuにDjangoアプリを設置したときの手順](https://qiita.com/moto2g/items/2071a0b660591213c251)
- [nginxとgunicornでDjangoの本番環境を構築する(2018年9月最新版)](https://qiita.com/takehiro_t59/items/bf4af2da35a4281f403f#gunicorn設定)