Docker化したDjangoアプリケーションをEC2で本番デプロイする #362
ついにアプリケーションを本番環境にアップする、ということができました。
まだ調整することが色々ありすぎる状況ですが、ひとまずインターネット経由で自分のアプリケーションにアクセスできたことは嬉しかったです。
手順をメモしていきます。
VPC関連を設定する
まずはネットワーク基盤を整える作業です。
東京リージョンにVPCを作成します。
作成方法はいろいろなブログがあるので割愛しますが、少し悩みそうなポイントだけメモしておきます。
次にサブネットです。VPC作成画面で同時に作成できます。
今回はパブリックサブネット1つのみを作成します。
IPアドレスの範囲をVPCよりやや狭めています。
インターネットゲートウェイと、そこにルーティングするためのルートテーブルは自動で作成されたものをそのまま使っています。
次にネットワークACLを設定します。
これはVPCに紐づくセキュリティルールのようなものです。
デフォルトでは全ての通信が許可されているので、新たに明示的なルールを設定します。
まず、インバウンドルールを以下のようにします。
アウトバウンドルールも同じです。
ルール番号100, 200, 300は全ての通信を許可するルールとして分かりやすいと思います。
ルール番号400の「1024-65535」が少し特殊です。
これは100, 200, 300だけだと、うまくEC2インスタンスの操作ができない事象があることへの対応です。
EC2インスタンスをSSHで操作する場合、クライアントPCへの返信は、動的に割り当てるポート番号を使って行われています。そのためPC端末に返信を通すには、ネットワークACLのアウトバウンドルールにカスタムTCPで、ポート番号を「1024-65535」と広範囲に許可設定する必要があります。
どのポート番号が使われても返信トラフィックが通るように許可しておくイメージですね。
余談ですが、なぜかインバウンドルールにもこの設定をしておかないと上手くいかない事象が確認されているらしく、上記ではそちらにも設定しておきました。
ひとまずこれでパブリックサブネットが1つ構成できました。
EC2インスタンスを立ち上げる
EC2インスタンスもサクッと立ち上げます。
それほど大きくないアプリケーション用の一般的な構成です。
セキュリティグループも設定しておきます。
インスタンスを起動する流れで一緒に新規作成することも可能です。
以下のように許可設定します。
これでEC2インスタンスの準備が整いました。
EC2にSSH接続する
以下はMacでのコード例です。
EC2インスタンス起動時に作成したキーペアを使って、ターミナルからSSH接続します。
ssh -i ~/.ssh/path/to/your/keypair ec2-user@パブリックIPアドレス
"-i"はキーペアで接続することを指しています。
"ec2-user"はAmazon Linux 2を使った時のデフォルトのユーザー名です。AMIが異なる場合、ユーザー名が異なることがあるのでご注意ください。
もしここで以下の警告が出た場合、
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '13.114.9.138' (ED25519) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/y.mori/.ssh/aws_ym202110/ym202110.pem' are too open.
It is required that your private key files are NOT accessible by others.
これはキーペアを他ユーザーが使える可能性がある、という警告なので、ファイルの権限を変更すればOKです。
chmod 600 /path/to/your/keypair
EC2に入れたら、以下のコマンドで現在地を確認したり、どんなフォルダがあるか確認してみましょう。
[ec2-user@ip-10-0-0-217 ~]$ pwd
/home/ec2-user
[ec2-user@ip-10-0-0-217 ~]$ ls -lf
. .. .bash_logout .bash_profile .bashrc .ssh
これでEC2インスタンスへの接続ができました。
EC2にDockerとdocker-composeをインストールする
EC2でDockerを使っていくための準備です。
まずは最新のDockerをインストールします。
$ sudo amazon-linux-extras install docker
Dockerデーモンを起動します。
$ sudo service docker start
dockerグループにec2-userを追加して、使えるようにします。
$ sudo usermod -a -G docker ec2-user
ここまで完了したら一旦インスタンスから抜けて、再度入り直してみます。
$ exit
ssh -i ~/.ssh/path/to/your/keypair ec2-user@パブリックIPアドレス
dockerのバージョン確認ができたら完了です。
$ docker --version
Docker version 20.10.17, build 100c701
ついでに、EC2インスタンスが再起動した場合にDockerデーモンも同時に起動する設定をしておきます。
$ sudo systemctl enable docker
以下のコマンドでenableと出れば成功です。
$ systemctl is-enabled docker
enabled
次にdocker-composeをインストールします。
以下のコマンドです。
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
ダウンロードしたdocker-compose(バイナリファイル)に実行権限を付与します。
sudo chmod +x /usr/local/bin/docker-compose
バージョン確認できれば成功です。
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
Dockerを使う準備が整いました。
EC2にローカルのソースコードを転送する
まずEC2インスタンスにアプリ用のディレクトリ作成します。
mkdir my-django-app
Macのターミナルに戻り、ローカルからscpコマンドでEC2へ必要なファイルをコピーします。
scp -i ~/.ssh//path/to/your/keypair -r /path/to/your/local/source_code/* ec2-user@パブリックIPアドレス:/home/ec2-user/my-django-app
ここまで来ればもう一息です。
ポート番号に気をつけてコンテナを立ち上げる
この記事では、EC2のパブリックIPアドレスをブラウザのURLに入力して、アプリがひとまず使えるかどうか、という内容になっています。
そのためHTTP通信(ポート番号80)で一旦動かしてみます。
docker runコマンドでもdocker-compose.ymlに記載する形でもどちらでも良いので、以下のようにマッピングしてコンテナを起動してください。
80:8000
これで80番に来た通信がdockerコンテナの8000番にマッピングされます。
ポート番号に気をつけてDjangoのrunserverを実行する
dockerコンテナが起動したらコンテナ内に入ります。
docker exec -it my-django-app bash
コンテナに入ったらrunserverします。ここでもマッピングに注意です。
DockerでDjangoを動かす場合、「0:8000」とする必要があります。
詳しくはこちらをご参照ください。
python manage.py runserver 0:8000
これでパブリックIPアドレスからアクセスできると思います。
ここまでお読みいただきありがとうございました!