Docker+DjangoをCircleCiでHerokuに継続デプロイする

# Docker+DjangoをCircleCiでHerokuに継続デプロイする
https://djan5.herokuapp.com/
[![Screenshot from Gyazo](https://gyazo.com/ad1e2edd7accf9a3c7fabc5d6640216f/raw)](https://gyazo.com/ad1e2edd7accf9a3c7fabc5d6640216f)

ファイル構成はこんな感じです。
GitHubリポジトリ
https://github.com/ErgoFriend/docker-django-circleci-heroku

```
.circleci/
   config.yml
   setup_heroku.sh
application/
   application/
   manage.py
docker-compose.yml
Dockerfile
requirements.txt
```

# すぐに試す

1. フォークなどで自分のリポジトリにクローンします。
2. herokuでアプリ・Token作成
 1. `heroku login` Herokuにログインします
 2. `heroku create アプリ名`でアプリを作成します
 3. `heroku authorizations:create -d "getting started token"`でトークンを作成します
 4. トークンはあとで使うのでコピー
3. CicleCIでGitHubリポジトリからプロジェクトを作成
4. CircleCIの環境変数(Environment Variables)にHerokuの認証情報を登録
5. リポジトリを更新するとCircleCIさんがHerokuにデプロイしてくれます

```
---CircleCIの環境変数---
HEROKU_API_KEY	トークン	
HEROKU_APP_NAME	アプリ名	
HEROKU_AUTH_TOKEN  トークン	
HEROKU_LOGIN  メールアドレス
```

### local
1. `docker-compose up`
2. http://localhost:8000/ へアクセス

# 書く

## .circleci

```yaml:.circleci/config.yml
version: 2
jobs:
  build:
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      - run:
          name: docker-compose build
          command: docker-compose build
  deploy:
    machine:
      image: circleci/classic:edge
    steps:
      - checkout
      # see: https://devcenter.heroku.com/articles/container-registry-and-runtime#using-a-ci-cd-platform
      - run:
          name: "build docker image"
          command: docker build --rm=false -t registry.heroku.com/${HEROKU_APP_NAME}/web .
      - run:
          name: setup heroku command
          command: bash .circleci/setup_heroku.sh
      - run:
          name: heroku maintenance on
          command: heroku maintenance:on --app ${HEROKU_APP_NAME}
      - run:
          # HEROKU_AUTH_TOKEN is generated by `heroku auth:token`
          name: "push container to registry.heroku.com"
          command: |
            docker login --username=_ --password=$HEROKU_AUTH_TOKEN registry.heroku.com
            docker push registry.heroku.com/${HEROKU_APP_NAME}/web
            heroku container:push web --app ${HEROKU_APP_NAME}
            heroku container:release web --app ${HEROKU_APP_NAME}
      - run:
          name: heroku maintenance off
          command: heroku maintenance:off --app ${HEROKU_APP_NAME}
workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
          filters:
            branches:
              only: master
```

```shell:setup_heroku.sh
#!/bin/bash
# git remote add heroku https://git.heroku.com/circleci-demo-python-flask.git
wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz
sudo mkdir -p /usr/local/lib /usr/local/bin
sudo tar -xvzf heroku-linux-amd64.tar.gz -C /usr/local/lib
sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku

cat > ~/.netrc << EOF
machine api.heroku.com
  login $HEROKU_LOGIN
  password $HEROKU_API_KEY
EOF
# machine git.heroku.com
#   login $HEROKU_LOGIN
#   password $HEROKU_API_KEY

# Add heroku.com to the list of known hosts
ssh-keyscan -H heroku.com >> ~/.ssh/known_hosts
```

## djangoアプリ
`django-admin startproject application`
最初に示したファイル構造になるように置きます。

```text:requirements.txt
dj-database-url==0.5.0
Django==2.1.2
django-heroku==0.3.1
gunicorn==19.9.0
psycopg2==2.7.5
pytz==2018.5
whitenoise==4.1
```

## Docker
```dockerfile:Dockerfile
FROM python:3.6-alpine
ENV PYTHONUNBUFFERED 1
# Creating working directory
RUN mkdir /application
WORKDIR /application
# Copying requirements
ADD requirements.txt /application
COPY ./application/ .
RUN apk add --no-cache --virtual .build-deps \
    ca-certificates gcc postgresql-dev linux-headers musl-dev \
    libffi-dev jpeg-dev zlib-dev \
    && pip install -r requirements.txt

# Run the app.  CMD is required to run on Heroku
# $PORT is set by Heroku
#CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000"]
CMD gunicorn --bind 0.0.0.0:$PORT application.wsgi
```

```yaml:docker-compose.yml
version: "3"

services:
  web:
    build: .
    command: python3 application/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/application
    ports:
      - "8000:8000"
```
## 引用
@Kesin11さんの[https://qiita.com/Kesin11/items/47079bc7f659e71b694c](https://qiita.com/Kesin11/items/47079bc7f659e71b694c) 
大変お世話になりましたm(__)m