Skip to main content

Django in AWS and Nginx

今年の春にDjangoを勉強して、gunicornとHerokuでデプロイしたアプリを 半年放置していたらサーバーエラーで動かなくなっていました。。。

AWSがKyashというデビッドカードを使えたので使ってみました。 下のサイト通りにしたらうまくいきました。(特に最初のサイト凄い!20分!)。 AWSで初めてデプロイしたので、作業中のメモをまとめました。

REF: [1], [2], [3], [4], [5], [6]

  1. 【20分でデプロイ】AWS EC2にDjango+PostgreSQL+Nginx環境を構築してササッと公開 - Qiita
  2. Djangoの既存プロジェクトをec2にデプロイ - Qiita
  3. 【AWSでサイト制作5】独自ドメイン設定 - Qiita
  4. AWS Route 53を使って独自ドメインのWebページを表示させてみよう | Avintonジャパン株式会社
  5. お名前.comで取ったドメインをAWSの「Route 53」で利用する | melon.Lab
  6. EC2上のDjangoアプリを独自ドメイン、SSL対応する - Qiita

AWS EC2

最初間違えてUbuntuを選んでなくて気づくのに時間かかりました。。。(;__;)

  1. サービス(左上) → EC2 → インスタンス(左側)→インスタンスの管理画面へ
  2. [インスタンスの作成] を押下 → AMI(Amazon Machine Image)にUbuntu選択 → 新規にキーを作成する → aws_ubuntu.pem をダウンロード
  3. インスタンスの状態がrunningかを確認
  4. chmod 400 aws-ubuntu.pem:パーミッションを変更→自分の~/.sshディレクトリとかに保管
  5. ssh -i "~/.ssh/aws_ubuntu.pem" ubuntu@<ip address>:ユーザー名はubuntu以外だとec2-userとか

Ubuntu env

Ubuntuのユーザーを作成し、作ったユーザーでsshできるようにします。

  1. sudo -i
  2. apt update -y
  3. adduser <app-user> : ubuntu以外はuseraddでまた違うらしい
  4. gpasswd -a user_name sudo : sudo グループに追加
  5. usermod -aG sudo <app-user>
  6. cp -r /home/ec2-user/.ssh /home/<app-user>/.ssh
  7. chown -R <app-user>:<app-user> /home/<app-user>/.ssh
  8. sudo su <app-user>
  9. chmod 0600 ~/.ssh/authorized_keys

Python env

  1. apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib
  2. sudo -H pip3 install virtualenv
  3. virtualenv <venv_name>
  4. source <venv_name>/bin/activate
  5. pip install django gunicorn psycopg2 psycopg2-binary Pillow

PostgreSQL

Herokuとかとだいたい同じでした。

  1. sudo -u postgres psql
  2. CREATE DATABASE <DB_NAME>;
  3. CREATE USER <DB_USERNAME> WITH PASSWORD '<DB_PASSWORD>';
  4. ALTER ROLE <DB_USERNAME> SET client_encoding TO 'utf8';
  5. ALTER ROLE <DB_USERNAME> SET default_transaction_isolation TO 'read committed';
  6. ALTER ROLE <DB_USERNAME> SET timezone TO 'UTC+9';
  7. 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

  1. 左カラムから、セキュリティグループ → セキュリティグループを作成
  2. 作成したものを右クリック → ルールの作成 →
    1. カスタムTCP▽,
    2. TCP,
    3. 8000
    4. 0,0,0,0/0
  3. インスタンス → 右クリック → ネットワーキング → セキュリティグループの変更 → 作成したものを選択
  4. python3 manage.py runserver 0.0.0.0:8000
  5. http://<your_ip>:8000で確認 → deactivate:venvぬける

gunicorn

gunicornの設定をします。自分はアクセスログとエラーログをホームディレクトリに保存してます。 gunicornの場所を間違えてはまったので気を付けてください。(venv使ったかで変わります)

  1. sudo vi /etc/systemd/system/gunicorn.service
  2. sudo systemctl start gunicorn.service
  3. 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を使います🔥

  1. sudo vi /etc/nginx/sites-available/<PJ_NAME>
  2. sudo ln -s /etc/nginx/sites-available/<PJ_NAME> /etc/nginx/sites-enabled/
  3. sudo systemctl restart nginx
  4. sudo ufw delete allow 8000
  5. 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

  1. セキュリティグループ → セキュリティグループにタイプ: HTTPのルールを追加
  2. (インスタンス→ ネットワーキング → セキュリティグループの変更→セキュリティグループ選択)←先ほどしてなかったら

Elastic IPs

  1. サイドメニュー → Elastic IPsからポチポチ
  2. Elastic IP アドレスの割り当て → 割り当て
  3. Elastic IP アドレスの関連付け → 関連付け

domain

ドメインとサーバーの繋げ方がいろいろあって混乱しますが、 お名前.comでのドメイン取得とRoute 53との連携(お名前.comへのRoute 53DNS登録) - のぴぴのメモ が各メリットデメリットがまとめられていて、結局ネームサーバーをいじるのがが一番楽でした

  1. AWS SERVICE → Route 53 → DNS 管理 → Create Hosted Zone → 取得したドメインを記入 → create
  2. ホストゾーンの詳細 → レコードセットの作成 → type:A, value: 取得したElastic IP記入 → 作成
  3. レコードセットの一覧に元々あるType:NSの四つのvalue(ns-**.**.**)を控えておく
  4. レコードセットの一覧のいずれを選択 → TTL(キャッシュする時間)を300sに設定
  5. お名前.com → ドメイン一覧 → 取得したドメインを選択 → ネームサーバー情報
  6. 他のネームサーバを利用 → ネームサーバに先ほどのNSの四つのvalue → 設定
  7. sudo vi /etc/nginx/sites-available/<PJ_NAME>server_name <your doman> <your Elastic IP>;
  8. vi <PJ_NAME>/<settings file>.pyALOWED_HOST=["<DOMAIN>","<Elastic IP>"]

SSL

HTTPSで繋がるように設定します。

  1. certbotでUbuntuとNginx選択→コマンド上から実行
  2. sudo add-apt-repository universeができないので、URLから直接入れる
  3. sudo certbot --nginxでポチポチ → whether or not to redirect HTTPで2を選択
  4. sudo certbot renew --post-hook "systemctl restart nginx":を試す
  5. sudo vi /etc/cron.d/letsencrypt0 1 * * 1 sudo certbot renew --post-hook "systemctl restart nginx"
  6. ec2 → セキュリティグループ → セキュリティグループにタイプ: HTTPSのルールを追加