はじめに
この記事はDocker で Python の Web フレームワーク、Django を動かすだけのハンズオンです。
ベストプラクティスや間違いがあれば、書き直していく予定です。
環境
-
ヤマダにペペロンチーノをこぼされた初代 Surface Book
- 実装 RAM 8GB
-
エディション Windows 10 Pro
-
バージョン 20H2
-
OS ビルド 19042.867
-
Chrome
- 89.0.4389.90(Official Build) (64 ビット)
Docker とは
ざっくり、コンテナと呼ばれる単位で環境を構築・管理することができるツール
OS レベルの仮想化によって動作して
アプリケーションとその動作環境をコンテナという単位で保存しておくことができる。
どこが凄いかと言えば、アプリケーションの環境をコンテナという単位で可搬することが可能なところ。
Docker 以前
Docker 以前は
アプリケーションに使われるライブラリやその他パッケージをドキュメント等に残し
同じ環境を作る操作を環境ごとにやる必要があった。同じ環境を作る操作を誤ったり、間違えたりするとキチンと動作しなかったり
想定とは違う動作になったりする為
同じ環境を作る操作以外にも環境構築の不具合に悩まされ、時間を取られるということがよくあった。
そこで一度作った環境をコンテナという単位でパッケージ化して
他の端末やサーバで扱えるようにしようとできたのが Docker である。
Docker 以後
どんなことが可能になったかをざっくり言うと
まずは開発環境の標準化が容易になり、環境セットアップ資料というモノから解放された(極端なことを言うと)
開発環境を他の人と共有するという概念が生まれた。
※以前にも仮想マシンという形で環境を共有することは可能でしたが Docker ほど簡単ではなかった。
環境のローリングアップデートがコンテナオーケストレーションによって簡単にできるようになった。
※とはいえ、Docker 技術にキャッチアップするのは割と難しい。現役のエンジニアでもそこそこ難しいところ。
ハンズオンセットアップ
ざっくり、流れを説明
- AWS 上に EC2 を構築
- Visual Studio Code で Remote SSH をインストール
- Remote SSH の設定
- EC2 に Docker をインストール
- EC2 に Docker-Compose をインストール
- Python3 のセットアップ
- pip3 で Django をインストール
- Django ローカルホストで実行
AWS 上に EC2 を構築
まずはコンソールを開いて。。。
と以前から CloudFormation の記事で EC2 の構築をやっているので
今回は IaC で構築します。
VPC を構築
まずは EC2 を置くためのサブネットを切る為に VPC を
CloudFormation で構築します。
CloudFormation の管理画面を開きます。
スタックの作成をクリック
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcCidrBlock:
Description: VpcCidrBlock
Type: String
Default: 10.0.0.0/21
Resources:
MainVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidrBlock
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: MainVpcfromCF
IGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: igw
Value: igw-cf
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MainVpc
InternetGatewayId: !Ref IGW
Outputs:
MainVpc:
Value: !Ref MainVpc
Export:
Name: MainVpcId
MainIgw:
Value: !Ref IGW
Export:
Name: MainIGWId
ファイル選択から vpc_network.yml をアップロードします。
スタック名は「vpc_network」とします。
スタックの作成には時間がかかりますので少し待ちましょう。
スタックの完成予想図。
サブネットを切る
VPC が構築できたらサブネットを切ります。
今回は django アプリケーション公開用にセキュリティグループに TCP でポート 8000 を開けます。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
AZ:
Description: AvailabilityZone
Type: String
Default: "ap-northeast-1a"
PublicSubnetCidrBlock:
Description: PublicSubnetCidrBlock
Type: String
Default: 10.0.2.0/24
Resources:
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Ref AZ
VpcId: !ImportValue MainVpcId
CidrBlock: !Ref PublicSubnetCidrBlock
Tags:
- Key: Name
Value: PublicSubnet
PubRT:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !ImportValue MainVpcId
Tags:
- Key: PublicRoute
Value: PublicRouteCf
PubToInternet:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PubRT
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !ImportValue MainIGWId
PubRTAssociate:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PubRT
secSSHGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: PublicSecGrp
GroupDescription: PublicSecGrp
VpcId: !ImportValue MainVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 8000
ToPort: 8000
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: PublicSecGrp
Outputs:
PublicSubnet:
Value: !Ref PublicSubnet
Export:
Name: PublicSubnet
PublicSecGrp:
Value: !GetAtt secSSHGroup.GroupId
Export:
Name: PublicSecGrp
ファイル選択から DjangoSubnet.yml をアップロードしてスタックを作成
スタックの作成には時間がかかりますので少し待ちましょう。
スタックの完成予想図。
キーペアを作成する
AWS コンソールから EC2 を開き、左ペインからキーペアを選択
キーペアを作成をクリック
キーペアを「Mykeypair」という名前で作成
EC2 を構築する
CloudFormation の画面に戻り、EC2 を作成する。
AWSTemplateFormatVersion: 2010-09-09
Resources:
myEC2Instance:
Type: AWS::EC2::Instance
Properties:
KeyName: Mykeypair
ImageId: ami-0992fc94ca0f1415a
InstanceType: t2.micro
Monitoring: false
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeviceIndex: "0"
GroupSet:
- !ImportValue PublicSecGrp
PrivateIpAddress: "10.0.2.10"
SubnetId: !ImportValue PublicSubnet
Tags:
- Key: Name
Value: PublicEC2
ファイル選択から public_django_ec2.yml をアップロード
スタックの完成予想図
セキュリティグループの確認
SSH 用のポートと公開用のポート番号が開かれていることを確認しましょう。
Visual Studio Code の設定
Visual Studio Code で Remote SSH をインストール
EC2 に SSH でログインする為に
VisualStudioCode のプラグインである「Remote SSH」をインストールします。
まだ、インストールをしていない人は以下のようにインストールと表示されていると思います。
インストールされている方は以下
Remote SSH の設定
Visual Studio Code の拡張機能 Remote SSH を設定します。
まず、Visual Studio Code の画面左下の緑ボタンを押します。
するとウィンドウの上部に選択肢が出るので「Connect to Host...」を選択
続いて「Configure SSH Hosts」を選択
Remote SSH の格納先を問われるのでユーザ名配下の.ssh を選択
以下の内容を環境に合わせて記載。
Host Django-EC2
HostName {パブリックIPアドレス}
IdentityFile {キーペア名(フルパス)}
User ec2-user
コンフィグを保存して閉じる。
再度、緑のボタンを押して Remote SSH 接続を開始すると新しいウィンドウが開かれる。
Django を試す
EC2 Django のセットアップ
ディレクトリを選択
ec2-user のホームディレクトリ「/home/ec2-user/」を選択
Visual Studio Code のウィンドウ左ペインから
ファイルを新規作成
以下のような Bash スクリプトを書いて EC2 の「/home/ec2-user/」に保存する。
# !/bin/bash
sudo yum update -y && \
sudo amazon-linux-extras install -y docker && \
sudo usermod -a -G docker ec2-user && \
sudo systemctl start docker.service && \
sudo systemctl status docker.service && \
sudo systemctl enable docker.service && \
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose && \
sudo yum install -y python37 python3-devel gcc jq tree git && \
git clone https://github.com/ymd65536/django_test.git && \
cd django_test/source && \
cd src && \
pip3 install -r requirements.txt --user && \
python3 manage.py migrate && \
python3 manage.py runserver 0.0.0.0:8000
&(アンパサンド)を使うことでコマンドの実行がこけた時の対策ができる。
例えば、今回のケースだと最初の yum がこけた場合は以降のコマンドは実行されない。
また、バックスラッシュでコマンド同士をつなぐとコマンド同士をつないでから実行するという意味になる。
作成した Bash スクリプトを実行する。
[ec2-user@ip-10-0-2-10 ~]$ pwd
/home/ec2-user
[ec2-user@ip-10-0-2-10 ~]$
[ec2-user@ip-10-0-2-10 ~]$ ls
django-install.sh
[ec2-user@ip-10-0-2-10 ~]$
[ec2-user@ip-10-0-2-10 ~]$ bash ./django-install
-------------------------------------
Performing system checks...
System check identified no issues (0 silenced).
April 10, 2021 - 13:30:12
Django version 2.0, using settings 'todobackend.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
HTTP で開く
EC2 上に Django によって作成された Web ページがオープンされたので
http://パブリック IP アドレス:8000 でアクセスする。
うまくいくとこんな感じに Django の REST Framework が表示される。
REST API で遊んでみる
http://localhost:8000/todos を開く
UI で操作するのも良いですがここでは curl で操作してみることにする。
# POSTでitemを作成する
curl -X POST -H "Content-Type: application/json" localhost:8000/todos -d '{"title": "推しのリプライを確認", "order": 1}'
※途中動かなくなったと思ってガチャガチャとリクエストを打ったら todo 番号がめちゃくちゃになりました。
# タスクを更新する(localhost:8000/todos/16 のアイテムのcompletedを更新)
curl -X PATCH -H "Content-Type: application/json" localhost:8000/todos/16 -d '{"completed":"true"}'
「推しのリプライを確認」16 の todo ステータスが true になりましたね。
他の 14 と 15 の todo を消してみましょう。
# タスクを削除する(localhost:8000/todos/14,localhost:8000/todos/15 のアイテムを削除)
curl -X DELETE -H "Content-Type: application/json" localhost:8000/todos/14
curl -X DELETE -H "Content-Type: application/json" localhost:8000/todos/15
todo 番号 14 と 15 が消えましたね。
todos の中身を見る
[ec2-user@ip-10-0-2-10 src]$ curl http://localhost:8000/todos | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 110 100 110 0 0 5789 0 --:--:-- --:--:-- --:--:-- 5789
[
{
"url": "http://localhost:8000/todos/16",
"title": "推しのリプライを確認",
"completed": true,
"order": 1
}
]
[ec2-user@ip-10-0-2-10 src]$
テストプログラムを実行
あらかじめ用意しておいたテストプログラムを実行する。
まずは、テスト用プログラムに利用するパッケージをインストールする為に
ディレクトリを移動する。
[ec2-user@ip-10-0-2-10 src]$ cd /home/ec2-user/django_test/source/src/
[ec2-user@ip-10-0-2-10 src]$ pip3 install -r requirements_test.txt --user
[ec2-user@ip-10-0-2-10 src]$ python3 manage.py test --settings todobackend.settings_test
----------------------------------------------------------------------
XML: /home/ec2-user/django_test/source/src/unittests.xml
Name Stmts Miss Cover
-----------------------------------------------------
todo/__init__.py 0 0 100%
todo/admin.py 1 1 0%
todo/migrations/0001_initial.py 5 0 100%
todo/migrations/__init__.py 0 0 100%
todo/models.py 6 6 0%
todo/serializers.py 7 0 100%
todo/urls.py 6 0 100%
todo/views.py 17 0 100%
-----------------------------------------------------
TOTAL 42 7 83%
----------------------------------------------------------------------
Ran 12 tests in 0.181s
OK
Destroying test database for alias 'default'...
[ec2-user@ip-10-0-2-10 src]$
rails test もテストにパスすると最後に OK が出るのでなんだか親しみやすいですね。
まとめ
今回は CloudFormation で VPC と EC2 を構築して django 環境を建て
Django REST Framework で遊んでみました。
次回は EC2 インスタンス上で Docker を扱っていきます。