Django in AWS and Nginx
今年の春にDjango を勉強して、gunicornとHerokuでデプロイしたアプリを 半年放置していたらサーバーエラーで動かなくなっていました。。。
AWSがKyashというデビッドカードを使えたので使ってみました。 下のサイト通りにしたらうまくいきました。(特に最初のサイト凄い!20分!)。 AWSで初めてデプロイしたので、作業中のメモをまとめました。
REF: [1], [2], [3], [4], [5], [6]
- 【20分でデプロイ】AWS EC2にDjango+PostgreSQL+Nginx環境を構築してササッと公開 - Qiita
- Djangoの既存プロジェクトをec2にデプロイ - Qiita
- 【AWSでサイト制作5】独自ドメイン設定 - Qiita
- AWS Route 53を使って独自ドメインのWebページを表示させてみよう | Avintonジャパン株式会社
- お名前.comで取ったドメインをAWSの「Route 53」で利用する | melon.Lab
- EC2上のDjangoアプリを独自ドメイン、SSL対応する - Qiita
AWS EC2
最初間違えてUbuntuを選んでなくて気づくのに時間かかりました。。。(;__;)
- サービス(左上) → EC2 → インスタンス(左側)→インスタンスの管理画面へ
- [インスタンスの作成] を押下 →
AMI(Amazon Machine Image)
にUbuntu選択 → 新規にキーを作成する →aws_ubuntu.pem
をダウンロード - インスタンスの状態がrunningかを確認
chmod 400 aws-ubuntu.pem
:パーミッションを変更→自分の~/.ssh
ディレクトリとかに保管ssh -i "~/.ssh/aws_ubuntu.pem" ubuntu@<ip address>
:ユーザー名はubuntu以外だとec2-userとか
Ubuntu env
Ubuntuのユーザーを作成し、作ったユーザーでsshできるようにします。
sudo -i
apt update -y
adduser <app-user>
: ubuntu以外はuseraddでまた違うらしいgpasswd -a user_name sudo
: sudo グループに追加usermod -aG sudo <app-user>
cp -r /home/ec2-user/.ssh /home/<app-user>/.ssh
chown -R <app-user>:<app-user> /home/<app-user>/.ssh
sudo su <app-user>
chmod 0600 ~/.ssh/authorized_keys
Python env
apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib
sudo -H pip3 install virtualenv
virtualenv <venv_name>
source <venv_name>/bin/activate
pip install django gunicorn psycopg2 psycopg2-binary Pillow
PostgreSQL
Herokuとかとだいたい同じでした。
sudo -u postgres psql
CREATE DATABASE <DB_NAME>;
CREATE USER <DB_USERNAME> WITH PASSWORD '<DB_PASSWORD>';
ALTER ROLE <DB_USERNAME> SET client_encoding TO 'utf8';
ALTER ROLE <DB_USERNAME> SET default_transaction_isolation TO 'read committed';
ALTER ROLE <DB_USERNAME> SET timezone TO 'UTC+9';
GRANT ALL PRIVILEGES ON DATABASE <DB_NAME> TO <DB_USERNAME>;
...
ALLOWED_HOSTS = ['{{ip adress}}']
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '{{DB_NAME}}',
'USER': '{{DB_USERNAME}}',
'PASSWORD': '{{DB_PASSWORD}}',
'HOST': 'localhost',
'PORT': '',
}
}
AWS
- 左カラムから、セキュリティグループ → セキュリティグループを作成
- 作成したものを右クリック → ルールの作成 →
カスタムTCP▽
,TCP
,8000
0,0,0,0/0
- インスタンス → 右クリック → ネットワーキング → セキュリティグループの変更 → 作成したものを選択
python3 manage.py runserver 0.0.0.0:8000
http://<your_ip>:8000
で確認 →deactivate
:venvぬける
gunicorn
gunicornの設定をします。自分はアクセスログとエラーログをホームディレクトリに保存してます。 gunicornの場所を間違えてはまったので気を付けてください。(venv使ったかで変わります)
sudo vi /etc/systemd/system/gunicorn.service
sudo systemctl start gunicorn.service
sudo systemctl enable gunicorn
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/<PJ_NAME>
ExecStart={{`which gunicorn` ででたpath. **/gunicornとか}}
--workers 3 --bind unix:/home/{{user}}/{{prj}}/{{prj}}.sock
{{prj_name}}.wsgi:application
--access-logfile "{{any_dir}}/access.log"
--error-logfile "{{any_dir}}/error.log"
[Install]
WantedBy=multi-user.target
nginx
nginxの設定をします。一度したらあんまり触れないです。viを使います🔥
sudo vi /etc/nginx/sites-available/<PJ_NAME>
sudo ln -s /etc/nginx/sites-available/<PJ_NAME> /etc/nginx/sites-enabled/
sudo systemctl restart nginx
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
server {
listen 80;
server_name <EC2のパブリックIP>;
location = /favicon.ico {access_log off; log_not_found off;}
location /static/ {
root /home/ubuntu/<PJ_NAME>;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/<PJ_NAME>/<PJ_NAME>.sock;
}
}
ec2
- セキュリティグループ → セキュリティグループにタイプ: HTTPのルールを追加
- (インスタンス→ ネットワーキング → セキュリティグループの変更→セキュリティグループ選択)←先ほどしてなかったら
Elastic IPs
- サイドメニュー → Elastic IPsからポチポチ
- Elastic IP アドレスの割り当て → 割り当て
- Elastic IP アドレスの関連付け → 関連付け
domain
ドメインとサーバーの繋げ方がいろいろあって混乱しますが、 お名前.comでのドメイン取得とRoute 53との連携(お名前.comへのRoute 53DNS登録) - のぴぴのメモ が各メリットデメリットがまとめられていて、結局ネームサーバーをいじるのがが一番楽でした
- AWS SERVICE → Route 53 → DNS 管理 → Create Hosted Zone → 取得したドメインを記入 → create
- ホストゾーンの詳細 → レコードセットの作成 → type:A, value: 取得したElastic IP記入 → 作成
- レコードセットの一覧に元々あるType:NSの四つのvalue(ns-**.**.**)を控えておく
- レコードセットの一覧のいずれを選択 → TTL(キャッシュする時間)を300sに設定
- お名前.com → ドメイン一覧 → 取得したドメインを選択 → ネームサーバー情報
- 他のネームサーバを利用 → ネームサーバに先ほどのNSの四つのvalue → 設定
sudo vi /etc/nginx/sites-available/<PJ_NAME>
→server_name <your doman> <your Elastic IP>;
vi <PJ_NAME>/<settings file>.py
→ALOWED_HOST=["<DOMAIN>","<Elastic IP>"]
SSL
HTTPSで繋がるように設定します。
- certbotでUbuntuとNginx選択→コマンド上から実行
sudo add-apt-repository universe
ができないので、URLから直接入れるsudo certbot --nginx
でポチポチ →whether or not to redirect HTTP
で2を選択sudo certbot renew --post-hook "systemctl restart nginx"
:を試すsudo vi /etc/cron.d/letsencrypt
→0 1 * * 1 sudo certbot renew --post-hook "systemctl restart nginx"
- ec2 → セキュリティグループ → セキュリティグループにタイプ: HTTPSのルールを追加