DjangoをAWS EC2にデプロイする方法
YouTube でゼロから開発するプログラミング動画チュートリアル「フルスタックチャンネル」を発信中の「はる」と申します。
Django を AWS EC2 にデプロイする方法を簡単に紹介します。
Docker を使用せずに、Django を EC2 にデプロイする方法になります。
GitHub Actions を使用して、自動デプロイも行います。
構成
Django と PostgreSQL を使用して、EC2 にデプロイします。
必要に応じて、S3 や SES を使用してください。
IAM 作成
IAM でユーザーを作成します。
FullAccess でポリシーを許可していますが、必要な権限だけ設定するようにしてください。
S3 バケット作成
必要に応じて S3 を作成します。
VPC 作成
VPC を作成します。
アベイラビリティーゾーン数は必要に応じて変更してください。
セキュリティグループ作成
セキュリティグループを作成します。
インバウンドルールで下記のポートをあけます
- SSH
- HTTP
- HTTPS
- PostgreSQL
EC2 インスタンス作成
先ほど作成した VPC とセキュリティグループを連携します。
サブネットは public1-ap-northeast-1a を指定
Ubuntu Server 22.04
インスタンス:t2.micro
RDS 作成
PostgreSQL を使用します。
先ほど作成した EC2 と連携します。
インスタンス:t3.micro
SES 作成
必要に応じて SES を作成します。
Django プロジェクト作成
Django プロジェクトを作成して、GitHub にアップロードしておきます。
SSH 接続
EC2 を作成したときに作成した xxx.pem を使用して SSH 接続します。
ssh -i "~/.ssh/xxxxx.pem" ubuntu@ec2-xxxxx.ap-northeast-1.compute.amazonaws.com
Python アップグレード
pyenv を使用して python のバージョンを3.11.8
に上げます。
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
exec "$SHELL"
sudo apt update
sudo apt install -y build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev curl libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
pyenv install -l | less
pyenv install 3.11.8
pyenv versions
pyenv global 3.11.8
python -V
Redis インストール
必要であれば Redis をインストールします。
sudo apt install redis-server
sudo nano /etc/redis/redis.conf
supervised を systemd に変更します。
. . .
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised systemd
. . .
sudo systemctl restart redis.service
sudo systemctl status redis
redis-cli
ping
リポジトリクローン
GitHub からリポジトリをクローンします。
sudo apt install nginx python3-pip python3-dev python3-venv libpq-dev
sudo -H pip3 install --upgrade pip
git clone https://github.com/xxx/xxxxxx.git
cd xxxxxx
Github の remote 先を変更
Github Actions から git pull するためには、origin をgit@github.com
にする必要があります。
git remote -v
origin https://github.com/xxx/xxxxxx.git
git remote set-url origin git@github.com:xxx/xxxxxx.git
環境変数作成
.env
ファイルを作成します。
データーベースは RDS の接続先情報を設定します。
必要に応じて変更してください。
nano .env
POSTGRES_NAME=xxxx
POSTGRES_USER=xxxx
POSTGRES_PASSWORD=xxxx
POSTGRES_HOST=xxxx.ap-northeast-1.rds.amazonaws.com
SECRET_KEY=xxx
DEBUG=False
AWS_ACCESS_KEY_ID=xxxx
AWS_SECRET_ACCESS_KEY=xxxx
AWS_STORAGE_BUCKET_NAME=xxxx
仮想環境構築
仮想環境を構築して、ライブラリインストール、静的ファイル収集、マイグレートを行います。
python -m venv venv
source venv/bin/activate
pip3 install --upgrade pip setuptools
pip3 install -r requirements.txt
python manage.py collectstatic
python manage.py migrate
python maange.py createsuperuser
nginx 内に static ファイルを設定する場合は、sudo コマンドで実行します。
sudo pip3 install django
sudo python manage.py collectstatic
Nginx 設定
Nginx の設定を行って、画面を表示します。
sudo nano /etc/nginx/sites-available/project-xxx
client_max_body_size を設定することによって、大容量のファイルも受け取れるようになります。
staticファイルの場所は、プロジェクトの設定によって変わります。
server {
listen 80;
server_name xx.xxx.xxx.xxx;
client_max_body_size 10g;
# nginx内にstaticファイルを設定する場合
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
ショートカットリンクを作成して、連携します。
sudo ln -s /etc/nginx/sites-available/project-xxx /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
nginx の設定は必要があれば変更してください。
sudo nano /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
client_max_body_size 10g;
sudo nginx -t
sudo systemctl restart nginx
この時点で、EC2 の IP アドレスにアクセスして、502 Bad Gateway が表示されることを確認します。
runserver で確認
Django を起動して、画面を確認します。
python manage.py runserver 0.0.0.0:8000
gnicorn で確認
gunicorn を使用して、Django を起動して、画面を確認します。
gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application
systemcmd 作成
system コマンドを作成して、リスタートしやすくします。
sudo nano /etc/systemd/system/project-xxx.service
[Unit]
Description=gunicorn
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/project-xxxx
ExecStart=/home/ubuntu/project-xxxx/venv/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 mysite.wsgi:application
[Install]
WantedBy=multi-user.target
動作コマンド
sudo systemctl start project-xxx
sudo systemctl restart project-xxx
sudo systemctl stop project-xxx
Celery サービス作成
必要であれば Celery を使用して、非同期処理を行います。
celery の system コマンドを作成します。
sudo nano /etc/systemd/system/celery.service
[Unit]
Description=Celery Service
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/project-xxx
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p /var/log/celery
ExecStartPre=/bin/chown ubuntu:ubuntu /var/log/celery
ExecStartPre=/bin/chmod 755 /var/log/celery
ExecStartPre=/bin/mkdir -p /var/run/celery
ExecStartPre=/bin/chown ubuntu:ubuntu /var/run/celery
ExecStartPre=/bin/chmod 755 /var/run/celery
ExecStart=/home/ubuntu/project-xxx/venv/bin/celery -A config worker -l info --pidfile=/var/run/celery/%n.pid --logfile=/var/log/celery/%n.log --concurrency=4
ExecStop=/home/ubuntu/project-xxx/venv/bin/celery multi stopwait worker -A config --pidfile=/var/run/celery/%n.pid
ExecReload=/home/ubuntu/project-xxx/venv/bin/celery -A config worker -l info --pidfile=/var/run/celery/%n.pid --logfile=/var/log/celery/%n.log --concurrency=4
Restart=on-failure
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
ログなどのフォルダ作成します。
sudo mkdir /var/log/celery
sudo chown -R ubuntu:ubuntu /var/log/celery
sudo chmod -R 755 /var/log/celery
sudo mkdir /var/run/celery
sudo chown -R ubuntu:ubuntu /var/run/celery
sudo chmod -R 755 /var/run/celery
動作コマンドです。
sudo systemctl start celery
sudo systemctl restart celery
sudo systemctl stop celery
コマンド
手動でコードを変更した場合は、project-xxx と celery のリスタートが必要になります。
sudo systemctl restart project-xxx
sudo systemctl restart celery
cat /var/log/celery/celery.service.log
cat /var/run/celery/celery.service.pid
SSH 公開鍵作成
Github Actions からデプロイをするために、ssh 公開鍵を作成します。
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 公開鍵を登録
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Deploy keys
Github の Settings の Deploy keys に id_rsa.pub の公開鍵を登録します。
Github Actions 環境変数
Github の Secret and variables の Actions に環境変数を追加します。
HOST_PROD ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
USERNAME_PROD ubuntu
SSH_KEY_PROD id_rsaの中身
AWS_ACCESS_KEY_ID xxx
AWS_SECRET_ACCESS_KEY xxx
GitHub Actions
Github Actions から git pull して、リスタートまでを自動的に実行します。
name: Deploy to EC2
on:
push:
branches:
- release/production
jobs:
build-and-deploy:
name: Build and Deploy to EC2
runs-on: ubuntu-22.04
steps:
- name: Checkout to the branch
uses: actions/checkout@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Deploy to EC2
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST_PROD }}
username: ${{ secrets.USERNAME_PROD }}
key: ${{ secrets.SSH_KEY_PROD }}
script: |
echo "Starting deployment process..."
cd /home/ubuntu/project-xxx
echo "Changed directory to project-xxx."
git pull
echo "Git pulled successfully."
source venv/bin/activate
echo "Activated virtual environment."
pip install -r requirements.txt
echo "Requirements installed."
python manage.py migrate
echo "Migrations applied."
# nginx内にstaticファイルを設定する場合はsudoコマンドで実行
python manage.py collectstatic --noinput
echo "Static files collected."
sudo systemctl restart project-xxx
echo "Project-xxx restarted."
sudo systemctl restart celery
echo "Celery restarted."
Celery ログの場所
バックグラウンドでエラーが発生した場合は、celery のログを確認します。
cd /var/log/celery
ドメイン設定
ドメインを取得します。
EC2 の IP アドレスは静的 IP アドレスに変更します。
Route53 でドメインを管理すると、簡単に EC2 の IP アドレスと紐付けることができます。
HTTPS 化
Let's Encrypt を使用します。
sudo apt-get install letsencrypt
sudo systemctl stop nginx
sudo letsencrypt certonly --standalone -d xxxx.co.jp
sudo nano /etc/nginx/sites-available/project-xxx
nginx の設定を変更します。
server {
listen 80;
listen [::]:80;
server_name xxx.co.jp;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name xxx.co.jp;
client_max_body_size 10g;
ssl_certificate /etc/letsencrypt/live/xxx.co.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.co.jp/privkey.pem;
# nginx内にstaticファイルを設定する場合
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
nginx のチェック
sudo nginx -t
sudo systemctl start nginx
sudo systemctl restart project-xxx
証明書自動発行
定期的に証明書を更新するために、cron を使用します。
sudo crontab -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
00 05 01 * * sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx
ソースコード
LINE 登録すると講座のソースコードがダウンロードできます。
新着の講座がいち早く届きますので、ぜひ登録をお願いします。
LINE お友達登録
フルスタックチャンネル
講座の不明点や個人開発の疑問点など何でもご質問ください。
さらに多くの知識と技術を共有し、また新しい学びの機会を提供することを楽しみにしています。
よろしくお願いします。
Discussion