LoginSignup
1
2

More than 3 years have passed since last update.

Djangoプロジェクトをデプロイするまでの練習 3回目 WebアプリケーションとCircleCIの準備

Posted at

ここでやること

ここでは、コンテナで動かす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するまでを行う。

流れとしては、
1. Djangoプロジェクトの作成→GitHubへpush
2. CircleCIでCI実行→CircleCIからGitHubのプロジェクトがcheckoutされてDockerイメージがbuildされる
3. 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

aws_ecr_repository.tf
resource "aws_ecr_repository" "sample-image" {
    name = "sample-image"
}
config.tf
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

aws_iam_user.tf
resource "aws_iam_user" "deploy-user" {
    name = "deploy-user"
}
aws_iam_policy.tf
resource "aws_iam_policy" "deploy" {
  name      = "deploy"
  path      = "/"
  description   = "deploy policy"
  policy    = file("aws_iam_policies/ecr_policy.json")
}
aws_iam_user_policy_attachment.tf
resource "aws_iam_user_policy_attachment" "deploy-attach" {
  user      = aws_iam_user.deploy-user.name
  policy_arn    = aws_iam_policy.deploy.arn
}
config.tf
terraform {
  backend "s3" {
    bucket = "保管するS3のバケットの名前"
    key    = "iam/terraform.tfstate"
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}
ecr_policy.json
{
    "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は下記の通り。

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へのアクセスキー関係の情報を環境変数に追加しておく。
image.png

この.circleci/config.ymlを含んだDjangoプロジェクトをGitHubにpushすると、
CircleCIのpipelineがRUN状態になり、ECRへDockerイメージがpushされる。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2