見出し画像

Docker化したDjangoアプリケーションをEC2で本番デプロイする #362

ついにアプリケーションを本番環境にアップする、ということができました。
まだ調整することが色々ありすぎる状況ですが、ひとまずインターネット経由で自分のアプリケーションにアクセスできたことは嬉しかったです。

手順をメモしていきます。


VPC関連を設定する

まずはネットワーク基盤を整える作業です。

東京リージョンにVPCを作成します。
作成方法はいろいろなブログがあるので割愛しますが、少し悩みそうなポイントだけメモしておきます。

[VPCの設定]
IPv4 CIDR:10.0.0.0/16
IPv6 CIDR:(不使用)
DNS ホスト名:有効
DNS 解決:有効

次にサブネットです。VPC作成画面で同時に作成できます。
今回はパブリックサブネット1つのみを作成します。
IPアドレスの範囲をVPCよりやや狭めています。

[サブネットの設定]
個数:パブリックサブネット1つのみ
IPv4 CIDR:10.0.0.0/24

インターネットゲートウェイと、そこにルーティングするためのルートテーブルは自動で作成されたものをそのまま使っています。

次にネットワークACLを設定します。
これはVPCに紐づくセキュリティルールのようなものです。
デフォルトでは全ての通信が許可されているので、新たに明示的なルールを設定します。

まず、インバウンドルールを以下のようにします。

アウトバウンドルールも同じです。

ルール番号100, 200, 300は全ての通信を許可するルールとして分かりやすいと思います。

ルール番号400の「1024-65535」が少し特殊です。
これは100, 200, 300だけだと、うまくEC2インスタンスの操作ができない事象があることへの対応です。

EC2インスタンスをSSHで操作する場合、クライアントPCへの返信は、動的に割り当てるポート番号を使って行われています。そのためPC端末に返信を通すには、ネットワークACLのアウトバウンドルールにカスタムTCPで、ポート番号を「1024-65535」と広範囲に許可設定する必要があります。

どのポート番号が使われても返信トラフィックが通るように許可しておくイメージですね。

余談ですが、なぜかインバウンドルールにもこの設定をしておかないと上手くいかない事象が確認されているらしく、上記ではそちらにも設定しておきました。

ひとまずこれでパブリックサブネットが1つ構成できました。


EC2インスタンスを立ち上げる

EC2インスタンスもサクッと立ち上げます。
それほど大きくないアプリケーション用の一般的な構成です。

AMI:Amazon Linux 2 (64ビット)
インスタンスタイプ:t2.micro
キーペア:新たに設定
VPCとサブネット:上記で作成したものを選択
パブリックIPの自動割り当て:有効化
ストレージを設定:デフォルトのまま

セキュリティグループも設定しておきます。
インスタンスを起動する流れで一緒に新規作成することも可能です。
以下のように許可設定します。

これで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アドレスからアクセスできると思います。

ここまでお読みいただきありがとうございました!


参考


この記事が気に入ったらサポートをしてみませんか?