Django Apache 連携 (HTTPS)

> **Djangoをmod_wsgiを用いてApacheと連携させる方法をまとめる。**

## 1. Apache2のインストール
```bash:shell
$ sudo apt install apache2
$ sudo apt install apache2-dev
```
ここでapache2-devをインストールしないとこの後インストールするmod_wsgiのインストールができない。

## 2. mod_wsgiのインストール
```bash:shell
$ pip install mod_wsgi
```

## 3. Let's EncryptによるSSl認証
これはhttps通信をするときに必要です。Let's Encryptの証明書取得、有効期限を自動更新してくれるcertbotを導入する。
```bash:shell
$ sudo apt install certbot python3-certbot-apache
$ sudo sudo certbot --apache
```
Route53やお名前ドットコムで取得したドメインを入力し、同意すると証明書が発行される。
本来は90日で有効期限が切れるがcertbotが自動更新してくれる。
`$ sudo systemctl status certbot.timer`
から１日2回更新してくれてることが確認できる。
有効期限の確認コマンドは
`$ sudo certbot certificates`
で確認できる。

## 4. config fileの作成
```bash:shell
$ vim /etc/apache2/sites-available/<conf-name>.conf
```
```.conf
LoadModule wsgi_module "/home/ubuntu/.local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-x86_64-linux-gnu.so"
WSGIPythonHome "/usr"
WSGIPythonPath "/home/ubuntu/.local/lib/python3.10/site-packages"

<VirtualHost *:443>
    ServerName <your-domain>
    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/<your-domain>/cert.pem
    SSLCertificateKeyFile  /etc/letsencrypt/live/<your-domain>/privkey.pem

    WSGIScriptAlias / "/home/ubuntu/<project-name>/<app-name>/wsgi.py"
    WSGIScriptReloading On

    <Files wsgi.py>
        Require all granted
    </Files>


    <Directory "/home/ubuntu/">
        Require all granted
    </Directory>

</VirtualHost>

<VirtualHost *:80>
    WSGIScriptAlias / "/home/ubuntu/<project-name>/<app-name>/wsgi.py"
    WSGIScriptReloading On

    <Files wsgi.py>
        Require all granted
    </Files>


    <Directory "/home/ubuntu/">
        Require all granted
    </Directory>
    RewriteEngine on
    RewriteCond %{SERVER_NAME} = <your-domain>
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
```
今回は仮想環境なしのEC2インスタンスで実装した。
最初の2行は`$ mod_wsgi-express module-config`で出力される値を、3行目はpythonのライブラリのpathを指定する必要があるため`$ sudo find -name site-packages`でpathを調べる。
今回はhttps通信をするので80番ポートは443にリダイレクトさせる。RewriteEngine～RewriteRuleまでがその設定。
ここでRequire all granted はすべて許可を意味する。

## 5. 権限の付与
このままapacheを立ち上げてアクセスするとPermission denied Errorが出る
そこでDjangoのプロジェクトディレクトリにAppachの権限を与える。
```shell:shell
$ sudo chown -R www-data:www-data /home/ubuntu/django
$ sudo chmod 755 /home/ubuntu
$ sudo chmod 755 /home/ubuntu/django
```
**全部必要かは確認が必要**

## 6. wsgi.pyの設定
このままだとNo module named 'app-name'と怒られる。そのためwsgi.pyに以下を追記する。
```python:wsgi.py
import os
from django.core.wsgi import get_wsgi_application
import sys

sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 追記
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/..') # 追記

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chatdiary.settings')

application = get_wsgi_application()
```

## 7. configの設定
```bash:shell
$ sudo a2dissite 000-dafault
$ sudo a2ensite <conf-name>
$ sudo service apache2 restart
```

### python-dotenvで作成した .envが読み込まれないエラーの解決
manage.py は .envを見つけられるが、wsgi.pyは見つけることができない。
```python:python
load_dotenv()
```
を以下のように変更する。
```python:python
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
load_dotenv(dotenv_path)
```


### 使えるコマンド一覧
Apacheのエラーログファイルを表示
`$ tail -f /var/log/apache2/error.log`
`$ cat /var/log/apache2/error.log`


Apacheのエラーログファイルを空にする
`$ sudo bash -c 'echo "" > /var/log/apache2/error.log'`