この記事は「エムスリー Advent Calendar 2016」の 9日目の記事です
昔プライベートで作ったwebアプリがあるのだけど、こいつをaws上にさくっと持っていくにはどうすればいいか考えました。結構古いOSと言語バージョンなので、できればdocker化して本番でもdockerで動かしたい。ちょっと調べたら、awsのelastic beanstalkはdockerをサポートしているので、これがよさそうです。(docker使わなくても、beanstalkはrubyやphpなどメジャーな言語の新しめverはサポートしていますが、今回の対象アプリの環境はサポート外だったので、docker使いました)。ということで、以下の構成を試してみます
- dockerhubのプライベートレジストリを使う
- awsはelastic beanstalkとRDSを使う
dockerhub
プライベートレジストリを作って、イメージ化したソースコードをpushしておく。なお、DBはelastic beanstalkでRDSにつなぐ想定なので、接続情報は、環境変数化して外から注入できるようにしておく
RDS_HOSTNAME
RDS_PORT
RDS_USERNAME
RDS_PASSWORD
RDS_DB_NAME
elastic beanstalk(以下、EB)
次はEBです
dockerhubの認証情報をS3においておく(権限注意)
まず、EBがdockerhubからイメージを取得できるようにするために、dockerhubの認証情報を用意して、S3に置く
- 2016/12/8現在、古い形式しかサポートしてないので一手間必要
- 具体的には、
~/.docker/config.json
(ローカルPCでdocker loginしたときに作成されるファイル)の中身を以下の通り少し編集したファイルを作って、それをS3の非公開バケットに保存する
現時点では、Elastic Beanstalk は古い ~/.dockercfg 形式の設定ファイルを必要とします。config.json ファイルを変換するには、外側の auths キーを削除し、古い形式と一致するように JSON ドキュメントを平坦化します
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_docker.container.console.html#docker-images-private
Dockerrun.aws.jsonを作成
次に、docker動かすためのEB専用のファイル(Dockerrun.aws.json)を作成する
Dockerrun.aws.json ファイルは、Docker コンテナを Elastic Beanstalk アプリケーションとしてデプロイする方法を記述するものです。この JSON ファイルは Elastic Beanstalk に固有です。ホストされたレポジトリで使用できるイメージでアプリケーションが実行される場合、Dockerrun.aws.json ファイルでイメージを指定し、Dockerfile を省略できますhttp://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_docker_image.html#create_deploy_docker_image_dockerrun
- 単一コンテナと複数コンテナが選べるが、今回は簡単な単一コンテナとする
- 公式サイトにあるように、どちらを選ぶかによってDockerrun.aws.jsonの書き方が異なる。単一コンテナの場合、v1形式となる
認証ファイルを [Dockerrun.aws.json] ファイルの [Authentication] パラメータ内に含む Amazon S3 バケットに関する情報を追加します。Authentication パラメータに有効な Amazon S3 バケットとキーが含まれていることを確認します。Amazon S3 バケットは、バケットを使用している環境と同じリージョンでホストする必要があります。Elastic Beanstalk は、他のリージョンでホストされている Amazon S3 バケットからファイルをダウンロードしません。
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_docker_image.html#docker-singlecontainer-dockerrun-privaterepo
とあるので、こんなjsonを作る
{
"AWSEBDockerrunVersion": "1",
"Authentication": {
"Bucket": "バケット名",
"Key": "ファイル名"
},
...
新規アプリの作成
これで下準備はOK。AWSコンソールでEBの画面を開いて、以下のとおりアプリケーションを作っていく
新しいアプリケーションを作成
環境を作成(ウェブサーバー環境を選択)
プラットフォームはdocker
アプリケーションコードはコードのアップロードを選択して、ここで、先ほど作ったDockerrun.aws.json
をアップロードする
しばらくたつと、デプロイ完了!表示されたurlにアクセスすると見れるようになってる!
便利すな〜
RDS
次は上記のEBにRDSを紐付けます。以下に書かれている通りに作っていけばよいです
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.managing.db.html
※なお本番稼動させる場合、RDSの方を別に作っておいて、それをEBが参照するようにしたほうがよさそうです
Elastic Beanstalk は、「Elastic Beanstalk 環境での Amazon RDS インスタンスの実行」をサポートします。この作業は環境の開発およびテストに適していますが、データベースインスタンスのライフサイクルをアプリケーション環境のライフサイクルに結び付けるため、実稼働環境に理想的なものではありません...環境からデータベースインスタンスを分離するには、Amazon Relational Database Service でデータベースインスタンスを実行し、アプリケーションの起動時にそれに接続するように設定します。これにより、複数の環境をデータベースに接続し、データベースに影響を与えないで環境を終了して、青/緑のデプロイメントでシームレスな更新を実行できるようになります
webアプリから接続できることを確認できたら、ローカルPCから接続する方法も一応試してみる
- 作成したRDSはデフォルトではローカルPCから接続できない
- 一時的にアクセスするために、RDSのセキュリティを変更(あとで戻しておくこと)
- 具体的には、RDSのセキュリティグループで「DBセキュリティグループ」の中に接続タイプ「CIDR/IP」で自分のIPを許可する(デフォルトだとDBセキュリティグループの中に「EC2 セキュリティグループ」しか設定されていないので、追加する)
- ローカルPCからmysqlコマンドでRDSに接続してみる
$ mysql -h xxx.xxx.xxx.rds.amazonaws.com -u <ユーザ名> -P <ポート> -p
Enter password:
接続できた!接続できること確認したら、セキュリティ設定は戻しておく
バッチは...
cronで動かしているようなバッチはどう動かせばいいかな。EBでは、cron.yamlというファイルでワーカー動かせるよう。SQSからhttp(POST)でキックされるエンドポイントを用意して動かすのかな。ここは別途調べるようということで、おしまい