はじめに
AWSのEC2インスタンスにSSH接続→git pullして手動でデプロイしていたのですが、CircleCIを使用して自動デプロイする手順をまとめました。
実現したいこと
GitHubにmasterブランチをpushした際に、CircleCIを動かしてDjangoのUnittestを実施。
テストにパスした際は、そのままEC2インスタンスにSSH接続してgit pullして最新のコードを反映させる。
なお、Djangoのアプリはdocker上で動かしています(docker-compose up -d)。
下記リンクがdockerの環境構成です。
Django+Nginx+MySQLの開発環境をDockerで構築する
EC2インスタンス
事前にgit docker docker-composeをインストールしておきます。
さらに、後述しますCircleCI用の公開鍵も記述します。
手順は下記にまとめました。
EC2インスタンスにgit,docker,docker-composeを導入、公開鍵の登録(CircleCI用)
CircleCI
対象のGitHubリポジトリをCircleCIに登録しておきます。
以下を実行します。
- 秘密鍵の登録
- EC2インスタンスのホスト名、ドメイン名の登録
 参照記事:Circle CIでwebサイトを自動デプロイ
秘密鍵の登録
CircleCIに使用できる鍵認証は形式が決まっていますので、それに従い作成します。
フォルダを作成し、そこに作成します。
参照:Adding an SSH Key to CircleCI
# 鍵の作成
$ mkdir ssh
$ ssh-keygen -m pem
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/kenkono/.ssh/id_rsa): ssh
CircleCIのコンソール画面で作成した秘密鍵を登録します。
Hostnameには任意の文字を記入します。

EC2インスタンスのホスト名、ドメイン名の登録
環境変数として登録します。
EC2の場合、ec2-user@ドメイン名かと思いますので、以下登録します。
HOST_NAME = ドメイン名
USER_NAME = ec2-user

CircleCIの実行コード
.circleci/config.ymlに記載したコードが、対象のGitHubレポジトリにpushされた際に実行されます。
以下記述内容です。
docker-composeを実行したいので、CircleCIでは仮想マシンであるcircleci/classic:edgeを指定します。
# circleCIのバージョン指定
version: 2
jobs:
  build:
    machine:
      image: circleci/classic:edge
    steps:
# Djangoのテストを実行
      - checkout
      - run:
          name: docker-compose up
          command: docker-compose up -d
      - run:
          name: sleep for launch db to migrate at Django
          command: sleep 10
      - run:
          name: migrate
          command: docker-compose run python ./manage.py migrate
      - run:
          name: test
          command: docker-compose run python ./manage.py test
      - run:
          name: docker-compose down
          command: docker-compose down
# EC2にSSH接続し、デプロイを実行
  deploy:
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      # CircleCIに登録した秘密鍵を呼び出す。
      - add_ssh_keys:
      - run: ssh ${USER_NAME}@${HOST_NAME} 'cd todoList && git pull && docker-compose run python ./manage.py migrate'
# テストが成功した場合のみ、deployを実行するようにします。
workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          # masterブランチがpushされた場合のみdeployするようにする。
          filters:
            branches:
              only: master
実行
git pushで一連の記述が動作します。
