EC2でDockerコンテナを起動し、Flaskを動かす(Flaskで簡単なWebサービスを作ってみる[第5回])

2020年9月6日

はじめに

PythonのWebアプリケーションフレームワークFlaskを使って、「消耗品買い物リスト」を作ってみます。
今回はAWSに構築したEC2上にDockerでコンテナを作成し、ブラウザからアクセスできるようにします。

前回まで

今回やること

Gitをインストールしてリポジトリをcloneし、Dockerコンテナを起動してFlaskを動かす、というところまでやっていきます。

  • 構成図
  • VPCセットアップ
  • EC2起動
  • 作業ユーザー作成 ← 前回の記事はここまで
  • Gitインストール
  • Dockerインストール
  • Flaskの起動・動作確認 ← 本記事はここまで

Gitインストール・設定

EC2サーバ上での作業になります。

Gitのインストール

$ sudo yum -y install git

鍵の作成

$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/oshiro/.ssh/id_rsa): /home/[user名]/.ssh/id_rsa_github
Enter passphrase (empty for no passphrase): (何も入力せずにEnter)
Enter same passphrase again: (何も入力せずにEnter)

Your identification has been saved in /home/[user名]/.ssh/id_rsa_github.

Your public key has been saved in /home/[user名]/.ssh/id_rsa_github.pub.

...
+---[RSA 2048]----+
| ...oo.+         |
|  .o=o*.         |
|   oo= o.        |
|  . . +  +       |
|   . + oS o      |
|    = * =        |
|   o B @oo.      |
|    = =+B+       |
|     ..*X=E      |
+----[SHA256]-----+

上のような画面が出ればOKです。

作成した公開鍵をGitHubに登録

$ cat ~/.ssh/xxx (作成した鍵の.pubの方)
出てきた結果をコピー
  • GitHubにログインした状態で
  • Settings > SSH and GCP keys
  • New SSH key
    • Title: 任意
    • Key: (公開鍵の中身をペースト)

GitHubへの接続確認

$ ssh -T git@github.com
Hi xxxx! You've successfully authenticated, but GitHub does not provide shell access.

うまくいくと上のように出ます。

できない場合

以下のようなエラーが出ることがあります。

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

/.ssh/configファイルを確認します。なければ作成し、以下のように追記します。

Host github github.com
    HostName github.com
    IdentityFile ~/.ssh/[秘密鍵パス]
    User git

秘密鍵周りの権限の設定もしておきます

$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/xxx(秘密鍵ファイル)
$ chmod 600 ~/.ssh/config

リポジトリをクローンしてくる

### リポジトリのclone
$ git clone git@github.com:tsoshiro/to-buy-list.git
...

$ ls
to-buy-list

無事、リポジトリをクローンできました。

Docker設定

Dockerをインストールして、リポジトリのDockerfileを読み込んでコンテナを起動します。

Dockerインストール

# インストール
$ sudo yum update -y
$ sudo yum install -y docker

# バージョン確認
$ docker --version
Docker version 19.03.6-ce, build 369ce74

# Docker起動
$ sudo yum update -y
読み込んだプラグイン:priorities, update-motd, upgrade-helper
No packages marked for update

$ sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:    .                                  [  OK  ]

# Dockerグループにユーザー追加
$ sudo usermod -a -G docker [user名]

# ログインし直して、起動確認
$ docker info
Client:
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
...

Dockerビルド

基本的には DockerでFlaskが動き、簡単なテストが通る状態を作るで実行した内容をやっていきます。

# リポジトリ直下に移動した状態で実行
$ docker build -t flask-app .

# 結果確認(pythondevというイメージが作られていることが確認できる)
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
flask-app           latest              f7aa7fbf34fc        3 seconds ago       885MB
python              3.7                 5c1cd4638fb7        13 days ago         876MB


# コンテナ起動しログイン(パスなどはEC2の環境に合わせて変更)
$ docker container run -it -p 8080:5000 -v ~/to-buy-list/src:/workdir --name to-buy-list flask-app /bin/bash

# コンテナに入れることを確認
root@19158c2c54d2:/workdir# 

Flaskを起動してみる

root@19158c2c54d2:/workdir# python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

ブラウザからアクセスしてみる

ブラウザのURLに[IPアドレス]:8080と打ち込んで、Hello worldが表示されれば成功です。

よくある失敗

コンテナのポートと、EC2のセキュリティグループ設定がズレていると表示されません。

例えば今回であれば、AWSコンソールからセキュリティグループを編集して、8080ポートのTCP接続を許可するようにしましょう。

テストも動かしてみる

root@19158c2c54d2:/workdir# python -m unittest test_app
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

当然通ります

まとめ

ここまでで、EC2のコンテナ上でFlaskを動かしてWebブラウザからアクセスできる状態まで進みました。

今後の基本的なフローとしては、

  • リポジトリを更新
  • EC2でプル

という流れを踏めば、まずはデプロイができるようになりました。
以降、本格的に開発を進めるにあたって、自動テスト・自動デプロイの設定もしていきます。
本格的な開発までが長いですがもう少し踏ん張ります。

余談: バックグラウンドでもFlaskを起動し続けるには?

Flaskを起動する際、python app.pyを使うと、SSH接続が切れるとFlaskも止まってしまい、実用的ではありません。
そこでnohupコマンドを使います。

$ nohup python app.py >out.log 2>err.log &

このように書くことでバックグラウンドでの実行が可能になります。

ちなみに、

  • out.logに標準出力
  • err.logにエラー出力

が記録されていきます。
ほったらかすとログファイルが溢れたり、リポジトリにゴミがたまるなんてことになりかねないので、どこかでログ記録の設定はします。

参考