この記事は Docker Advent Calendar 2018 6日目の記事です。
はじめに
エウレカでは開発したBotやアプリケーションについて、Dockerコンテナ化がなされていれば、会社が用意した環境にデプロイするような仕組みを整えています。
本日は、初学者向けに、Go+Docker+GCP+Terraformを使ったコンテナ作成について紹介をします。
事前準備
とりあえず、Dockerだけインストールしておいてください。
あと、2年前にも似ている記事を書いているので、そこも参照すると良いかもしれません。
※古いので、そこだけはご了承を
Go without Go
普段、サーバーで開発をしているため、ローカルではほとんど開発を行っていません。環境構築が必要になったときは必ずDockerコンテナを利用しています。それに合わせて、今回はDockerをメインに開発を行います。また、サンプルリポジトリとして3年前に作ったbase64のアプリケーションサーバーを用います。
これを、ひとまずローカル環境で動かします。私はMacを使うことが多いのでMacにクロスコンパイルしたバイナリを作成します。
# ホストとマウントさせて、go getを行う(必要があれば編集をローカルで行うため) $ docker run -v ~/go:/go golang go get -v github.com/kaneshin/base64server # ホストにあるコードをdockerコンテナ経由でビルドします $ docker run -v ~/go:/go -e GOOS=darwin -e GOARCH=amd64 golang go install github.com/kaneshin/base64server # クロスコンパイルしたバイナリを起動します $ ~/go/bin/darwin_amd64/base64server # 別のセッションでアプリケーションにリクエストを送り、テキストをエンコードします $ curl 'localhost:8080/encode?v=hoge' aG9nZQ==
docker run golang
docker run golang
を行うことで、docker-library/golangに管理されているDockerコンテナを取得し、実行します。
各Dockerfileを読めば、どのような情報でコンテナが用意されているかがひと目でわかるので、確認が必要ならば目視チェックします。
ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" WORKDIR $GOPATH
golangのコンテナでは、 $GOPATH
に /go
が設定されているため、基本的にはここをマウントポイントとしています。
Dockerfileの準備とコンテナの実行
さて、先ほどはローカル環境にバイナリを作成して起動をしました。これだけだと、Goの環境を整備せずにコンテナを使っただけに過ぎません。では、次に、このアプリケーションをコンテナ化してしまいます。
FROM golang:1.11.2 RUN mkdir -p /go/src/github.com/kaneshin/base64server ADD . /go/src/github.com/kaneshin/base64server/ RUN go build -o main github.com/kaneshin/base64server EXPOSE 8080 CMD ["./main"]
ADD . /go/src
だけでも構わないのですが、本家に合わせていくスタイルや規模の大きいプロジェクトなどを考慮すればこのようにした方がラクです。
$ cd ~/go/src/github.com/kaneshin/base64server # Dockerfileを元にビルド $ docker build -t base64server . # ビルドしたコンテナを起動 $ docker run -p 8080:8080 base64server # 別のセッションでアプリケーションにリクエストを送り、テキストをエンコードします $ curl 'localhost:8080/encode?v=hoge' aG9nZQ==
ここまではコンテナに慣れている人は簡単ですね。
GCPと連携する
Cloud Source Repositories
Cloud Source Repositories を開き、ポチポチとGitHubのリポジトリと連携します。
連携が完了すると、github_kaneshin_base64server
のようなリポジトリ名でリポジトリが作成されています。
Cloud Buildと連携する
ここからは、gcloud
と gsutil
が必要になるので、ここもDockerでどうにかします。
# cloud-sdkのDockerコンテナをpullしてくる docker run -ti google/cloud-sdk gcloud version # GCPに認証を通す docker run -ti --name gcloud-config google/cloud-sdk gcloud auth login # VolumeからCredentialsを引き継ぎしつつ、gsutilでTerraform state用のバケットを作成 docker run --rm -ti --volumes-from gcloud-config google/cloud-sdk gsutil mb -p [YOUR-PROJECT-ID] -c multi_regional -l Asia gs://terraform-state
Terraformで環境構築
ここはDockerじゃなくて実際のTerraform使います。
$ cd ~/go/src/github.com/kaneshin/base64server/terrafrom # 必要なプラグインを入れるおまじない $ terraform init # Placeholderになっている変数を適切に注入 $ terraform plan -var 'project_id=[YOUR-PROJECT-ID]' -var 'credentials_file_path=[YOUR-CREDENTIALS]' -var 'env=prod' $ terraform apply -var 'project_id=[YOUR-PROJECT-ID]' -var 'credentials_file_path=[YOUR-CREDENTIALS]' -var 'env=prod'
下記のように、Cloud Build上でトリガーが設定されます。
そして、トリガーが発火されると、Container Registryにコンテナが作成されます。
おわりに
3, 4年前からDockerは触っていますが、周辺環境もキレイに整ってきていて昔と比べて本当に使いやすくなったの一言ですね。Dockerは入りが難しいと思われがちですが、パターンさえ覚えてしまえば下手な環境構築よりかも簡単です。