Web アプリケーションの分野では、コンテナ化が一般的になっているだけでなく、Web アプリケーションをパッケージングして配信するための好ましいモードになっています。
コンテナによって、アプリケーションをパッケージ化し、デプロイメント・プラットフォームに合わせてアプリケーションを再構成したり適応させたりすることなく、どこにでもデプロイすることができます。
コンテナ化の最前線にいるのがDockerで、これはプラットフォームに依存しないコンテナでアプリケーションをパッケージ化して実行するために使用されるツールです。
このコンテナ化の時代にはサーバーレス技術も隆盛を極め、ユーザーがコンテナ化されたソフトウェアをデプロイできるプロバイダーが増え、開発者がアプリケーションをデプロイする際の有力な選択肢になりつつあります。
アプリケーションを構築することは重要ですが、エンドユーザーがそれを利用できるようにすることも製品の重要な部分です。
この投稿では、Dockerを使用してDjangoアプリケーションをパッケージ化し、AmazonのEC2にデプロイします。
EC2とは何ですか?
AmazonのElastic Compute Cloud(EC2)は、開発者がクラウド上に仮想マシンのインスタンスを作成することで、アプリケーションをプロビジョニングして実行できるようにするサービスである。
また、EC2はトラフィック量に基づいてリソースが割り当てられる自動スケーリングも提供する。
他のAWSサービスと同様に、EC2はSQS(Simple Queue Service)やS3(Simple Storage Service)など、他のAmazonサービスと容易に統合することができる。
EC2には、次のような特徴がある。
- インスタンス。インスタンス:開発者がアプリケーションを実行するための仮想コンピューティング環境またはサーバー。インスタンス:開発者がアプリケーションを実行するための仮想コンピューティング環境またはサーバーで、現在のニーズやシナリオに合わせて、メモリ、ストレージ、計算能力、ネットワークリソースを設定できる。
- Amazon Machine Images (AMI)。Amazon Machine Images (AMI): インスタンスを作成するために使用される事前設定されたテンプレート。AMIは、必要に応じてオペレーティングシステムやプリロードされたソフトウェアと一緒に提供され、カスタマイズが可能です。
- インスタンスストアボリューム。インスタンスストアボリューム:データを一時的に保存するために使用されます。インスタンスストアボリューム:データを一時的に保存するために使用され、インスタンスの終了時にデータは削除される。
- Elastic Block Store(EBS)ボリューム。Elastic Block Store(EBS)ボリューム:データを永続的に保存する目的でインスタンスに接続される、可用性と信頼性の高いストレージボリューム。EBSボリュームに保存されたデータはインスタンスよりも長持ちし、1つのインスタンスに複数のボリュームをマウントすることができます。
- セキュリティグループ。プロトコル、IPアドレス範囲、ポートを指定してインスタンスへのアクセスを制御する仮想ファイアウォール。これにより、インスタンスへのトラフィックを制御・制限することができる。
これらは、AmazonのElastic Compute Cloudの機能の一部であり、詳細はドキュメントで確認することができます。
前提条件
このチュートリアルでは、Webアプリケーションを構築し、AmazonのEC2サービスにデプロイします。
そのためには、以下のものが必要です。
- Amazon Web Services (AWS)のアカウントで、EC2へのアクセスを提供します。このリンクから、この記事の作業には十分な無料階層にサインアップすることができます。
- Djangoアプリケーションを構築するために、Python 3.6+、Pip、Virtualenvがインストールされていること。
- アプリケーションをパッケージ化し、ポータブルなだけでなく、Dockerがインストールされている場所ならどこでも実行できるコンテナで簡単に実行するために、Dockerも必要になります。
DjangoアプリケーションのDocker化
まず、シンプルな Django アプリケーションを構築し、簡単にデプロイできるようにコンテナ化することから始めます。
まず、プロジェクト用のフォルダを作成することから始めましょう。
$ mkdir django_ec2 && cd $_
そして、仮想環境を作成します。
$ virtualev --python=python3 env --no-site-packages
そして、それを有効にして、 Django をインストールしましょう。
$ source env/bin/activate
$ pip install Django
単純なプレースホルダ Django アプリで十分です。
プロジェクトを起動するために必要なことは、 django-admin
の startproject
コマンドを実行することだけです。
$ django-admin startproject django_ec2_project
次に、プロジェクトのディレクトリを入力してみましょう。
$ cd django_ec2_project
そして、軽量な開発サーバーを起動します。
$ python manage.py runserver
すべてがうまくいけば、localhost:8000
でアプリケーションにアクセスすると、次のようなランディングページが表示されるはずです。
Django アプリケーションをパッケージングする前に、全てのソースへのトラフィックを許可する必要があります。
これは django_ec2_project/django_ec2_project/settings.py
にある ALLOWED_HOSTS
設定を修正することで実現できます。
# Add the asterisk in the empty list
ALLOWED_HOSTS = ['*']
Note: 実稼働環境では、ワイルドカードを残すことはお勧めできません。
代わりに自分の本番サイトのドメインを使ってください。
これでデプロイするのに十分なので、プロジェクトのルートに Dockerfile
を追加して、アプリケーションをコンテナ化しましょう。
FROM python:3.6-alpine
MAINTAINER Robley Gori <ro6ley.github.io
EXPOSE 8000
RUN apk add --no-cache gcc python3-dev musl-dev
ADD . /django_ec2
WORKDIR /django_ec2
RUN pip install -r requirements.txt
RUN python django_ec2_project/manage.py makemigrations
RUN python django_ec2_project/manage.py migrate
CMD [ "python", "django_ec2_project/manage.py", "runserver", "0.0.0.0:8000" ]
このDockerfileには、アプリケーションがどのようにコンテナ化され、実行されるかが記述されています。
まず、Python 3.6がインストールされたベースイメージを使用します。
また、ポート 8000
を公開します。
これはコンテナへのトラフィックをこのポートに向けることを意味し、Django アプリケーションがここから実行されることを意味します。
いくつかのパッケージをイメージにインストールし、Django アプリケーションを django_ec2
ディレクトリに追加します。
私たちの Django プロジェクトはコンテナ化されているので、仮想環境を作成する必要はありません。
したがって、要件を直接インストールし、マイグレーションを実行します。
最後に、コンテナの起動時に実行されるコマンドを追加します。
このコマンドは、私たちの場合、Django アプリケーションを起動し、ポート 8000
で実行します。
このトピックについてより詳細な説明が必要な場合は、Dockerizing Python Applications の記事を参照してください。
次のステップは、上記の Dockerfile を使って Docker イメージをビルドすることです。
その前に、環境にインストールされている依存関係をファイルに保存しておきます。
$ pip freeze > requirements.txt
そして、Dockerイメージのビルドを行います。
$ docker build . -t django_ec2
このコマンドにより、DockerはカレントフォルダにあるDockerfileを探し、それを使ってイメージをビルドし、django_ec2
というタグをつけます。
イメージのビルドが完了したら、次のコマンドでイメージを実行します。
$ docker run -d -p 8000:8000 django_ec2
このコマンドは Django アプリケーションが動作しているコンテナを起動し、 -p
フラグで指定されたように、我々のマシンのポート 8000
をコンテナのポート 8000
にマップし、 -d
フラグで指定されたようにヘッドレス(端末を閉じても)で実行します。
もう一度 localhost:8000
にアクセスすると、同じ Django ランディングページが表示されるはずです。
イメージの準備ができたら、EC2へのデプロイを容易にするためにDockerhubに公開する必要があります。
Dockerhubは、あらゆる目的でカスタマイズされたDockerイメージを作成し、共有できるようにする、準備の整ったイメージのレジストリである。
また、AWSのような他のプラットフォームからアクセスできるようにイメージを公開することも可能です。
今回のケースでは、Dockerhubにイメージを公開し、それをEC2に取り込んでデプロイすることにします。
まず、Dockerhubにアカウントを作成し、端末でログインしてイメージを公開します。
$ docker login
ログインしたら、ユーザー名をタグ付けして、Dockerhubにプッシュします。
$ docker tag django_ec2 <dockerhub_username/django_ec2
$ docker push <dockerhub_username/django_ec2
これで、次のステップ、AmazonのElastic Compute Cloudにアプリケーションをデプロイする準備が整いました。
EC2へのデプロイ
W
AMIを選択する
最初のステップでは、インスタンスを作成するために使用するAmazon Machine Image (AMI)を選択する必要があります。
Red Hat、Ubuntu Server、Windows Serverなどのオプションが表示されます。
このデモでは、コンテナを実行するようにカスタマイズされ、Dockerと一緒に出荷されているイメージが必要です。
検索バーに ECS
と入力すると、そのイメージを見つけることができます。
Amazon ECS-Optimized Amazon Linux 2は、私たちのシナリオに理想的なので、それを選択します。
インスタンスの種類を選択
インスタンス用のAMIを選択したら、次はインスタンスタイプを選択します。
ここで選択したものが、CPU、メモリ、ストレージ、ネットワーク性能など、インスタンスが持つリソースの数を決定します。
今回はAWSの無料ティアであるため、汎用的なインスタンスであるt2.micro
インスタンスを使用し、1CPUと1GiBのメモリを搭載しています。
このリストには、計算能力、メモリ、またはストレージに最適化された、より強力なインスタンスタイプが含まれています。
インスタンスの構成
インスタンスの種類を選択したので、次のステップでは、インスタンスの詳細を指定します。
このステップでは、デフォルトのオプションに変更を加えることはありません。
ストレージの追加
偽
タグを追加する
AWSでは、リソースにラベルを付けることで、目的、アクセス、環境などの観点でリソースを分類することができます。
タグは必須ではありませんが、数が増えるにつれてリソースを識別するのに役立つため、強く推奨します。
セキュリティグループの設定
この投稿でセキュリティグループを定義しましたが、このステップでは、新しいセキュリティグループを作成するか、既存のセキュリティグループを使用するかのいずれかで設定します。
ここでは、サーバーに受け入れるトラフィックを定義する新しい Security Group を作成します。
最初のルールは SSH のルールで、ポート 22
経由で SSH のトラフィックをインスタンスに許可します。
ソースは Anywhere
に変更し、Custom TCP
の新しいルールを追加して、ソースを Anywhere
に、ポートの範囲を 8000
に設定します。
これで、ポート 8000
経由で Django ウェブアプリケーションにアクセスできるようになります。
レビュー・発売
このステップでは、インスタンスの構成の詳細が表示され、検証を行います。
インスタンスを起動する前に、この時点で設定を編集することも可能です。
全てに問題がなければ、最後に “Launch” をクリックし、インスタンスを起動することができます。
インスタンスを起動する前に、実行中のインスタンスにアクセスできるようにするためのキー・ペアを作成する必要があります。
Django アプリケーションを実行するためには、インスタンスにサインインし、そこにデプロイする必要があります。
秘密鍵は私たちを認証し、デプロイを進めるためにインスタンスにアクセスできるようにするために使われます。
インスタンスの起動確認は次のページで表示されます。
EC2インスタンスへのアクセス
秘密鍵のダウンロードとインスタンスの起動が完了したら、ログインしてアプリケーションをデプロイしてみましょう。
そのためには、先ほどダウンロードした .pem
ファイルと、ターミナルウィンドウが必要です。
Amazon Linux AMI の場合、デフォルトのユーザ名は ec2-user
です。
インスタンスに接続するには、インスタンスのパブリックDNSも必要で、これはEC2コンソールダッシュボードのインスタンスの詳細セクションで確認することができます。
秘密鍵のファイルがあるフォルダーでターミナルを開いてみましょう。
保護されていない鍵ファイル」という警告が表示されないように、まず鍵のパーミッションを変更する必要があります。
$ chmod 400 <private_key_file_name
次に、鍵ファイルと一緒に ssh
ユーティリティを使用して、インスタンスに接続します。
$ ssh -i <private_key_file_name ec2-user@<public_dns
__| __| __|
_| ( __ Amazon Linux 2 (ECS Optimized)
____|___|____/
For documentation, visit http://aws.amazon.com/documentation/ecs
12 package(s) needed for security, out of 25 available
Run "sudo yum update" to apply all updates.
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
[ec2-user@ip-###-##-##-## ~]$
Dockerhubからアプリケーションイメージを取得し、docker run
コマンドを使用して実行します。
$ docker run -d -p 8000:8000 <dockerhub_username/django_ec2
Docker イメージがインスタンスに取り込まれ、正常に実行されると、SSH でアクセスしたのと同じアドレスで、Web 上の Django アプリケーションにアクセスできるようになります。
アクセスすると、次のように表示されます。
Django アプリケーションが AWS Elastic Compute Cloud 上で稼働しています。
結論
この投稿では、Dockerを使用してDjangoアプリケーションをコンテナ化し、それをAmazonのEC2サービスに正常にデプロイしました。
また、EC2とは何か、開発者として私たちに何を提供してくれるのか、そして私たちのウェブアプリケーションをエンドユーザが利用できるようにするために、どのように活用できるのかを学びました。
このプロジェクトのスクリプトのソースコードは、こちらのGitHubで見ることができます。
.