ここでやること
ここでは、コンテナで動かすWebアプリケーションを作成し、アプリケーションのCIの設定までをおこなう。CIでは、テスト、Dockerイメージのビルド・イメージをECRへプッシュするところまで実施して準備を確認する。
イメージをビルド
docker build -t djangoproject:ver1 .
8000ポートでコンテナを起動
docker run -itd --name djangoproject --mount type=bind,source="$(pwd)"/code/,target=/code/ djangoproject:ver1
djangoプロジェクトをスタート
docker exec djangoproject djang-admin startproject djangoproject /code/project
helloappアプリをスタート
docker exec djangoproject python3 /code/project/manage.py startapp helloapp /code/project/hello
作業用Docker関係のファイル
この作業用Dockerというのは、主にTerraformによるAWSへの環境構築のために使用する。私の環境がWindowsなのでDockerを使用しているだけなので、必要が無ければあえて作成する必要はないかも。
Dockerfile
From python:3.7
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y \
vim
RUN mkdir /terraform
WORKDIR /terraform
RUN mkdir .aws
ADD .aws .aws
RUN pip install awscli
RUN wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip && \
unzip ./terraform_0.12.24_linux_amd64.zip -d /usr/local/bin/
RUN cp -r .aws ~
イメージをビルド
docker build -t work:ver1 .
コンテナを起動
docker run -itd --name work --mount type=bind,source="$(pwd)"/terraform/,target=/terraform/ work:ver1
GitHubの準備
githubにリポジトリを2つ作成(djangoproject用とterraform用)
途中、.gitignoreにterraformのプラグインが除外されておらず、100MB以上のファイルとしてはねられてしまいました。下記のコマンドで対応できました。参考にさせていただいた記事のリンクはこちら。
https://www.walbrix.com/jp/blog/2013-10-github-large-files.html
$ git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch でかいファイル.tar.gz' \
--prune-empty --tag-name-filter cat -- --all
$ git commit --amend -CHEAD
$ git push
CircleCIでのCIの設定
CircleCIでは、Djangoプロジェクトのビルドと、ビルドしたDockerイメージをECRにpushするまでを行う。
流れとしては、
- Djangoプロジェクトの作成→GitHubへpush
- CircleCIでCI実行→CircleCIからGitHubのプロジェクトがcheckoutされてDockerイメージがbuildされる
- buildが終わったら、DockerイメージがECRにプッシュされる。
という感じです。
なので、以下の準備をしました。
- terraform用とDjangoプロジェクト用のGitリポジトリを作成
- terraformを使ったECRリポジトリの作成
- CircleCIがECRへDockerイメージをpushするためのIAMユーザー作成
- DjangoプロジェクトのCIのためのCircleCIの設定
ECRリポジトリの作成
ECRリポジトリについては、下記のようなディレクトリ構成で作成しました。
terraform/
|-ecr/
|-.terraform/
|-aws_ecr_repository.tf
|-config.tf
resource "aws_ecr_repository" "sample-image" {
name = "sample-image"
}
terraform {
backend "s3" {
bucket = "保管するS3バケットの名前"
key = "ecr/terraform.tfstate"
region = "ap-northeast-1"
}
}
provider "aws" {
region = "ap-northeast-1"
}
CircleCI用のIAMユーザーの作成
IAM用のterraformのディレクトリ構成はこんな感じ。
terraform/
|-iam/
|-.terraform/
|-aws_iam_policies/
|-ecr_policy.json
|-aws_iam_policy.tf
|-aws_iam_user_policy_attachment.tf
|-aws_iam_user.tf
|-config.tf
resource "aws_iam_user" "deploy-user" {
name = "deploy-user"
}
resource "aws_iam_policy" "deploy" {
name = "deploy"
path = "/"
description = "deploy policy"
policy = file("aws_iam_policies/ecr_policy.json")
}
resource "aws_iam_user_policy_attachment" "deploy-attach" {
user = aws_iam_user.deploy-user.name
policy_arn = aws_iam_policy.deploy.arn
}
terraform {
backend "s3" {
bucket = "保管するS3のバケットの名前"
key = "iam/terraform.tfstate"
region = "ap-northeast-1"
}
}
provider "aws" {
region = "ap-northeast-1"
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": "*"
}
]
}
上記のtfファイルをもとに、terraform init、terraform plan、terraform applyを実行することでIAMユーザーを作成した。また、作成したユーザーの認証情報からアクセスキー関係の情報を取得しておく。これは、次のステップのCircleCIのセットアップの際に環境変数で設定しておく。
CircleCIのセットアップ
Djangoプロジェクト用にセットアップ。circleci/config.ymlは下記の通り。
version: 2.1
orbs:
python: circleci/python@0.2.1
jobs:
build-and-test:
executor: python/default
steps:
- checkout
- python/load-cache
- python/install-deps
- python/save-cache
- run: sudo chmod u+x manage.py
- run:
command: ./manage.py test
name: Test
build-image:
docker:
- image: docker:18.09.0
steps:
- checkout
- setup_remote_docker
- run:
name: install aws cli
command: |
apk add --no-cache --update py-pip
pip install awscli
- run:
name: login ecr
command: |
$(aws ecr get-login --no-include-email --region ap-northeast-1)
- run:
name: build image
command: |
docker build -t ${ECR_DOMAIN}:$CIRCLE_SHA1 -t ${ECR_DOMAIN}:latest .
- run:
name: Push docker image
command: |
docker push ${ECR_DOMAIN}:$CIRCLE_SHA1
docker push ${ECR_DOMAIN}:latest
workflows:
main:
jobs:
- build-and-test
- build-image:
requires:
- build-and-test
filters:
branches:
only: master
また、下記の画像の通り、AWSへのアクセスキー関係の情報を環境変数に追加しておく。
この.circleci/config.ymlを含んだDjangoプロジェクトをGitHubにpushすると、
CircleCIのpipelineがRUN状態になり、ECRへDockerイメージがpushされる。