CodeBuild で Amazon Linux 2 の Python 3 アプリケーションの Docker イメージを作成する

2018.01.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、藤本です。

最近、Python 3 で書いたクローリング、スクレイピングのバッチアプリケーションを開発しています。日次バッチでコスト効率よく使いたかったため、バッチアプリケーションの実行環境に AWS Batch を利用しています(Fargate が東京リージョンに来ていれば、ECS 単体でいいんだけどなぁ)。本エントリでは Amazon Linux 2 のベースイメージから Python 3 実行環境を作成する Dockerfile、buildspec.yml がいつかまた作ることになりそうだったので備忘録として残しておきます。

概要

AWS Batch は ECS をラップしたサービスであり、動作するアプリケーションは Docker イメージから起動します。Docker コンテナのアプリケーションをデプロイするには基本的に Docker イメージの再作成が必要です。ソースコードが変更になる度、手作業でイメージを作成するのは大変ですよね?できれば、リリースブランチにプッシュされたらイメージ作って、ECR にプッシュするところまでは自動でやりたいですよね?

今回の本題ではないですが、現在想定しているバッチアプリケーションの開発フローは以下のような構成です。

プルリクベースの GitHub 運用です。 プルリクや、プルリクブランチへのプッシュは CodeBuild の Webhook 連携により都度テストを実行します。 デプロイはリリースブランチへのプッシュに対して行います。本エントリではリリースブランチにプッシュされた時に Docker イメージを作成します。

やってみる

CodeBuild の設定方法は他のエントリに記載されているので、Dockerfile と、buildspec.yml だけ記載します。

Dockerfile
FROM amazonlinux:2
ADD . .
RUN amazon-linux-extras install python3
RUN yum install -y gcc python3-devel
RUN pip3 install -r requirements.txt
ENTRYPOINT python3 main.py

ベースイメージは Amazon Linux 2 の最新版を使いたかったためイメージタグは2を指定します。現在latestは Amazon Linux 1 なのでご注意ください。

https://hub.docker.com/_/amazonlinux/

Amazon Linux 2 の Python 3 インストールは Extras Repository を利用します。詳細は下記エントリを参照してください。

Amazon Linux 2のExtras Library(amazon-linux-extras)を使ってみた

buildspec.yml
version: 0.2
 
phases:
  pre_build:
    commands:
      ### ECR へログイン
      - $(aws ecr get-login --region ${AWS_DEFAULT_REGION} --no-include-email)
      ### ECR リポジトリの URL の定義。IMAGE_NAME は CodeBuild プロジェクトの環境変数で外部注入
      - REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_NAME}
      ### イメージタグ名の定義。GitHub の commit id を利用して、イメージと、ソースコードをマッピング
      - IMAGE_TAG=$(echo $CODEBUILD_SOURCE_VERSION)
  build:
    commands:
      ### Dockerfile からイメージを作成
      - docker build -t $REPOSITORY_URI .
      ### タグ打ち
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      ### ECR リポジトリへプッシュ
      - docker push $REPOSITORY_URI:$IMAGE_TAG

まとめ

いかがでしたでしょうか? 割と汎用的に使いそうだったので一つのエントリとしてまとめました。どなたかの参考になると幸いです。