自己紹介
じゅんじゅんと言うニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。
HAL大阪3回生です。(2018/03/11現在)
イベントや、勉強会に参加してるので是非お会いした際はお声掛けください!
HEW2018 モダンなWebサービスの作成(インフラ編)とは
これは僕の学校のイベントの発表をQiitaの記事としてあげておくためのエントリーです。
気になる方はこちらをご覧ください。
インフラ以外には
があります。
環境
今回はAmazon Web ServiceのECS(Elastic Container Service)とRDS(Relational Database Service)を使っていて、Docker ContainerをECSへCircleCIからオートデプロイしています。
以下、軽く用語の説明になります。
ECS
Amazon Elastic Container Service (ECS) は、非常にスケーラブルかつ高性能なコンテナ管理サービスで、Docker コンテナに対応しており、Amazon EC2 インスタンスのマネージドクラスターでアプリケーションを簡単に実行できます。
わかりやすい解説: Amazon EC2 Container Service(ECS)の概念整理
RDS
Amazon Relational Database Service (Amazon RDS) を使用すると、クラウド内でリレーショナルデータベースを簡単に設定、運用、およびスケールできます。ハードウェアのプロビジョニング、データベースのセットアップ、パッチ適用、バックアップなどの時間がかかる管理タスクを自動化しながら、コスト効率とサイズ変更可能なキャパシティーを提供します。
わかりやすい解説: weblio/Amazon RDS
Docker
「Docker(ドッカー)」とは、非常に軽量なコンテナ型のアプリケーション実行環境である。dotCloud社(現Docker社)が開発し、2013年にオープンソースのプロジェクトとして公開された。ソフトウェアの高速な配布・実行や容易なイメージのカスタマイズ、導入運用の手軽さ、豊富なプレビルドイメージの提供などの理由により、当初はソフトウェアの開発やテスト段階における利用が多かったが、現在ではパブリッククラウドからオンプレミスシステムまで、さまざまなシーンで急速に普及しつつある。
わかりやすい解説: Dockerについて基本から最近追加された機能までまとめ
CircleCI
Create custom environments, apply Workflows for control over your build pipeline, enjoy flexible resource allocation, and more.
わかりやすい解説: CircleCIで出来るコト
オートデプロイ
今回はCircleCIを使って、GitHubのmasterブランチにpushした時にコンテナをアップロードし、ECSに通知することを意味するとします!
動画にまとめました
手順を全てスクショとってやっているとかなり記事の画面を占領してしまうのでYouTubeにアップロードしましたので、そちらをご覧ください
開発
今回はインフラなので、
- circleci
- Dockerfile
- Makefile
の説明をしていきます。
Dockerfile
まずDockerfile
FROM alpine:3.6
WORKDIR /root
ENV GO_ENV production
RUN set -x \
&& apk upgrade --no-cache \
&& apk --update add tzdata \
&& cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
&& apk del tzdata \
&& rm -rf /var/cache/apk/*
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
ADD ./cmd/main .
ADD ./public ./public
ADD ./view ./view
ADD ./config.yml ./config.yml
ADD ./cmd/migrate .
ADD ./cmd/seed .
EXPOSE 8000
# Run it
ENTRYPOINT ["./main"]
1つずつ説明していきます。
FROM alpine:3.6
OSは軽量なalpine
を使います
ENV GO_ENV production
これでDockerの環境変数を設定します。
今回は、production
モードで動いてほしいのでproduction
を指定します。
ADD ./cmd/main .
ADD ./public ./public
ADD ./view ./view
ADD ./config.yml ./config.yml
ADD ./cmd/migrate .
ADD ./cmd/seed .
ここで、必要なファイルをDockerに移します。
EXPOSE 8000
# Run it
ENTRYPOINT ["./main"]
ここで、8000番ポートを開けておく設定をします。
AWSのECSのときのコンテナのポートと揃えてください。
goはビルドしているのでmain
をたたけばサーバーが立ち上がるので、ENTRYPOINT
に./main
を指定します。
これで、docker run
されたときに、./main
を叩いてくれてサーバーが立ち上がります。
Makefile
create:
cp config.yml.template config.yml
migrate:
go run migration/main.go
seed: migrate
go run seed/main.go
go/build:
make -f .circleci/ci.mk go/build
docker/build: go/build
make -f .circleci/ci.mk docker/build
docker/push: go/build
env NODE_ENV=production npm run build
make -f .circleci/ci.mk docker/build
make -f .circleci/ci.mk login
make -f .circleci/ci.mk docker/push
makefileは基本的にコマンドなどを書いておきます。
今回ここのmakefileはローカルで触る場合を基本意識していてCIから触る方は.circleci/ci.mk
に書いています。
なので、それを呼ぶ形にしています。
CircleCI
# ECS
ECS_ID := 871669327434
AWS_REGION := ap-northeast-1
APP := hew2018
export AWS_REGION
export AWS_DEFAULT_REGION=$(AWS_REGION)
DOCKER_IMAGE := $(ECS_ID).dkr.ecr.$(AWS_REGION).amazonaws.com/$(APP):latest
login:
aws configure set region $(AWS_REGION)
aws configure set aws_access_key_id $$AWS_ACCESS_KEY_ID
aws configure set aws_secret_access_key $$AWS_SECRET_ACCESS_KEY
$$(aws ecr get-login --no-include-email --registry-ids $(ECS_ID) --region $(AWS_REGION))
go/build:
make create
env GOOS=linux env GOARCH=amd64 env CGO_ENABLED=0 go build -o ./cmd/main main.go
env GOOS=linux env GOARCH=amd64 env CGO_ENABLED=0 go build -o ./cmd/migrate migration/main.go
env GOOS=linux env GOARCH=amd64 env CGO_ENABLED=0 go build -o ./cmd/seed seed/main.go
docker/build:
docker build -t $(DOCKER_IMAGE) --build-arg GO_ENV=production .
docker/push:
docker push $(DOCKER_IMAGE)
docker/deploy:
.circleci/ecs-deploy --enable-rollback --timeout 300 --cluster $(APP) --service-name $(APP) --image $(DOCKER_IMAGE)
基本のデプロイの流れとして、
- goをビルドする
- dockerをビルドする
- docker imageをpushする
- ecs-deployでdeploy作業をする
になっています。
基本変える場所としては
ECS_ID := 871669327434
AWS_REGION := ap-northeast-1
APP := hew2018
この3つだと思います。
ECS_IDはECSでリポジトリを作った際にかえってきたidです。
AWS_REGIONはAWSのリージョンを入力してください。
APPは、アプリケーション名を入力します。
この情報は全てリポジトリを作ったときに表示される
871669327434
.dkr.ecr.ap-northeast-1
.amazonaws.com/hew2018
:latest
みたいなところから取得できます。
.circleci/config.yml
ここでcircleciの設定をかきます。
まずCircleCIで、GitHubのリポジトリを紐付けておくのを忘れないでください
あと、AWSのIAM
をつくってそのユーザーのアクセスキー
をCircleCIの設定のほうにかいておいてください。
version: 2
jobs:
test:
working_directory: /go/src/github.com/konojunya/HEW2018
docker:
- image: makki0205/deploy
steps:
- checkout
- run:
name: npm install
command: npm install
- run:
name: component build
command: env NODE_ENV=production npm run build
- run:
name: go build
command: make -f .circleci/ci.mk go/build
- save_cache:
key: build-{{ epoch }}
paths:
- .
deploy:
working_directory: /go/src/github.com/konojunya/HEW2018
docker:
- image: makki0205/deploy
steps:
- setup_remote_docker:
reusable: true
- restore_cache:
keys:
- build
- run:
name: docker build
command: make -f .circleci/ci.mk docker/build
- run:
name: aws login
command: make -f .circleci/ci.mk login
- run:
name: docker push
command: make -f .circleci/ci.mk docker/push
- run:
name: deploy
command: make -f .circleci/ci.mk docker/deploy
workflows:
version: 2
build_and_deploy:
jobs:
- test
- deploy:
requires:
- test
filters:
branches:
only: master
CircleCIはバージョン2を使うので2の設定になっています。
流れはworkflow
のままです。
これでオートデプロイの環境を構築できました!
オートデプロイができるようになっているとプロダクトのコードに集中できるので少し設定が多くて難しいですがやっておいたほうがよいでしょう!
注意点として、
CircleCIの中でDockerを使う時は
- setup_remote_docker:
reusable: true
これを入れておかないと、使えないです。
あとがき
Twitterしています!ぜひフォローください。 @konojunya
ソースコードは konojunya/HEW2018 にあります!