Herokuにデプロイ出来るHerokuメンテナンス用のDockerコンテナを使ってデイリーで本番環境をステージングにバックアップ

[Heroku Advent Calendar 2016](http://qiita.com/advent-calendar/2016/heroku) 6日目の記事です。なんだかんだ3年連続ぐらいHerokuのAdvent Calendarを書いていますね


# はじめに

このクラウドワークスさんの記事に触発された。

[Herokuで本番サービスを運用する際にやっておきたいこと & 構成の事例](http://engineer.crowdworks.jp/entry/2016/09/05/154304)

上記の記事内の[「本番とデータ同期できるpreview環境を追加する」](http://engineer.crowdworks.jp/entry/2016/09/05/154304#DBのバックアップ設定をしておく)の辺りでやっている、以下のシェル・コマンドを実行できるDockerコンテナを作成した。

* Production環境のHeroku PostgresをStaging環境にコピー
* コピーしたDBから個人情報をマスク
* AWS S3にあるPuroduction環境バケットをStaging環境用のバケットに同期

このDockerコンテナをHerokuにデプロイしている。

このように、あまり知られていないがHerokuにも実はDockerコンテナをデプロイ出来るしくみがいつの間にか出来ているのだ。
https://devcenter.heroku.com/articles/container-registry-and-runtime

今回のように、herokuのバックアップコマンドを実行したりAWSのCLIを実行させるには、
既存のビルドパックを作るより(というかビルドパックでなんとかできそうだけど調べてない)
Dockerコンテナを作ったほうが開発マシンで動作確認もしやすいことから便利かなと思う。

Dockerコンテナの場合Heroku以外にもDockerコンテナをデプロイ出来る環境であればどこのクラウド環境でも、適当な社内サーバでも構築することが出来るのも良いところ過と思う。


## リモートリポジトリ

#### Github
https://github.com/konyu/heroku-aws-backup

#### Docker hub
https://hub.docker.com/r/konyu/heroku-aws-backup/


## AWSとHerokuのAPIキー取得方法
AWSとHerokuのAPIキーを事前に取得してメモしておく

それぞれの取得方法のURLは以下のとおり

### AWS access key and secret key
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html

### Heroku api token
https://devcenter.heroku.com/articles/authentication#api-token-storage

## ローカル環境でのビルド方法

```sh
git@github.com:konyu/heroku-aws-backup.git
cd heroku-aws-backup
docker build --rm -t heroku-aws-backup .
```

## ローカル起動方法
--envでAWSとHerokuの環境変数をつけて起動する

```sh
docker run -it --rm --env AWS_ACCESS_KEY_ID=xxxxxxx \
--env AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxx \
--env AWS_DEFAULT_REGION=ap-northeast-1 \
--env HEROKU_API_KEY=xxxxxxxxxxxxx \
heroku-aws-backup bash
```

## バックアップのシェルファイルの修正

ここで書いているようにGithubのリポジトリをクローンして利用している場合、

バックアップ用のサンプルファイルがsh/backup.shにあるので適宜、自分の環境に合わせて書き換える

DockerfileのFromに書いて利用している場合はsh/backup.shを作成して適宜シェルファイルを書き換えると良いだろう

https://github.com/konyu/heroku-aws-backup/blob/master/sh/backup.sh

```
# sample backup shell
# echo "start daily buckup!!"

# echo "== stopping worker =="
# heroku ps:scale worker=0 -a APP_BE_BAKED_UP

# echo "== copying database to preview from production =="
# heroku pg:copy ORIGINAL_DB_NAME DB_TO_BE_COPIED --confirm APP_BE_BAKED_UP -a APP_BE_BAKED_UP

# echo "== clearing jobs =="
# heroku run rake jobs:clear -a APP_BE_BAKED_UP

# echo "== copying s3 bucket to staging from production =="
# aws s3 sync --delete --acl public-read s3://ORIGINAL_BUCKET s3://BUCKET_TO_BE_COPIED

# echo "== starting worker =="
# heroku ps:scale worker=1 -a APP_BE_BAKED_UP
```


# Herokuで動かす

### Heroku cliをインストール
HerokuのCLIコマンドをインストールしていなければ、下記URL内のOSを選択して使えるようにしておくこと

https://devcenter.heroku.com/articles/heroku-command-line

### Heroku container registryを追加

```
heroku plugins:install heroku-container-registry
```

## Herokuにデプロイする

Move to this repository directory

### Herokuにログイン

```
heroku login
> enter your id and password
```

### Create application(新規作成の場合)

```
heroku create APP_NAME_YOU_WANT
```

### Modify application(修正の場合)

git remoteにherokuにデプロイ出来るよう追加

```
heroku git:remote -a APP_NAME_YOU_WANT
```

### Herokuにデプロイする

```
heroku container:push web
```

## 環境変数の設定

```
環境変数の設定
heroku config:set AWS_ACCESS_KEY_ID=xxxxxxx AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxx AWS_DEFAULT_REGION=ap-northeast-1 HEROKU_API_KEY=xxxxx -app APP_NAME_YOU_WANT
```

# Schedulerの追加

```
heroku addons:create scheduler:standard -app APP_NAME_YOU_WANT
```

# Schedulerにシェルを実行を追加する
実行するシェルはフルパスで書くこと。

```heroku run bash -a APP_NAME```で起動したときのホームディレクトリからの相対パスで書いてもうまく動かないので注意だ

![2016-11-18 11 39 35](https://cloud.githubusercontent.com/assets/1217706/20417217/33c8071c-ad87-11e6-9da7-0b755a21ea1b.png)