はじめまして!
2019年度新入社員の大川です。現在は、WEBサービス開発グループでOJT中です。
皆さん、Dockerを知っていますか?すでに使っている人も多いと思いますが、中には「名前は知ってるけど使ったことは無い」という人もいると思います。私もその一人で、「コンテナを作って共有とか出来るんでしょ?」それくらいのイメージでした。
そんなDocker初心者の私が、Dockerを用いてGo言語の環境を構築しWEBサーバーを立ち上げてみたので、そのことについて書いていきたいと思います。
また、Go1.12からGo Modulesという新機能が登場したので試してみました。
環境
Docker:18.06.1
Docker Compose:1.21.0
Go言語:1.12.6
Dockerとは
DockerとはDocker社が提供している、コンテナ型の仮想環境を構築するためのプラットフォームです。
PCの中に軽量な仮想マシンを構築でき、コンテナを入れ替えれば様々な仮想環境を扱うことが出来ます。よってプロジェクトごとに開発環境を変えることが出来ます。
また、コンテナを共有することも出来るので、開発環境をそのまま本番環境に移植したり別のPCで同じ環境を作ることが出来ます。
これだけですごく便利だということが分かると思います。
今回の流れ
今回は、コンテナを作成するための処理は、DockerfileとCompose file (docker-compose.yml) に記述し、 $ docker-compose up と入力すればコンテナを作り出せる状態にしようと思います。
Dockerのインストール
Dockerをインストールしていない人は以下のサイトを参考にインストールしましょう。
- Mac版
https://docs.docker.com/docker-for-mac/install/ - Windows版
https://docs.docker.com/docker-for-windows/install/
必要なプログラムを記述する
最終的なディレクトリ構造は以下のようになるので必要なファイルを作成していきます。
1 2 3 4 5 6 7 8 |
go_app ├── Dockerfile ├── docker-compose.yml ├── go.mod ├── go.sum ├── log │ └── error.log └── main.go |
Dockerfile
Dockerfileとは、必要なパッケージや設定を記述することで、自分でDockerイメージを作ることが出来るファイルです。
今回はGo言語のバージョン1.12.6をベースに、イメージを作成していきます。
また、今回はGo Modulesでモジュールを管理をするのでGO111MODULEという環境変数をonにする必要があります。
go mod download で go.mod に記述されている依存パッケージをダウンロードします。
1 2 3 4 5 6 7 |
FROM golang:1.12.6 LABEL maintainer "[my name]" WORKDIR /go/src ENV GO111MODULE=on RUN go mod download EXPOSE 8080 CMD ["go", "run", "/go/src/main.go"] |
Compose file (docker-compose.yml)
Compose fileとは、複数のコンテナを利用するときに記述するファイルです。
今回は、バインドマウント (ローカルのファイルをコンテナで利用できる状態に) するために利用しました。
1 2 3 4 5 6 7 8 |
version: '3' services: web: build: . volumes: - ./:/go/src ports: - "8080:8080" |
go.mod
パッケージの依存関係を記述していきます。
1 2 3 4 5 6 7 8 9 10 11 |
module nifty/[my name] go 1.12 require ( github.com/pkg/errors v0.8.1 // indirect github.com/stretchr/testify v1.3.0 // indirect go.uber.org/atomic v1.4.0 // indirect go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.10.0 ) |
main.go
Webサーバーを立ち上げてログを収集するためのプログラムを書いていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package main import ( "fmt" "net/http" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) var logger *zap.Logger func init() { config := zap.Config{ Level: zap.NewAtomicLevelAt(zap.DebugLevel), Development: false, Sampling: &zap.SamplingConfig{ Initial: 100, Thereafter: 100, }, Encoding: "json", EncoderConfig: zapcore.EncoderConfig{ TimeKey: "ts", LevelKey: "level", NameKey: "logger", CallerKey: "caller", MessageKey: "msg", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.EpochTimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, OutputPaths: []string{"stderr"}, ErrorOutputPaths: []string{"stderr"}, } config.OutputPaths = []string{"./log/error.log"} logger, _ = config.Build() } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Please check the log.") logger.Info("Hello nifty", zap.String("key", "value")) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } |
今回は、net/httpパッケージを利用してWebサーバーを立ち上げます。
http.HandleFuncでは、第1引数にパスを、第2引数に処理を指定することでリクエストを処理できるようになります。
http.ListenAndServeを用いてサーバーを起動します。
また、zapを使ってログを収集してみようと思います。
実行する
必要なファイルを記述したら、Dockerfileと同じディレクトリで以下のコマンドを入力しましょう。オプションで -d を付けるとバックグラウンドでの実行になります。
1 |
$ docker-compose up -d |
URLにアクセスしてみましょう!
1 |
$ curl http://localhost:8080/ |
Please check the log. と表示されたらlogファイルの中のerror.logの中身を確認してみましょう。
1 |
{"level":"info","ts":1561598062.632202,"caller":"src/main.go:46","msg":"Hello nifty","key":"value"} |
このような内容が記述されていれば成功です。お疲れ様でした!
終わりに
今回は、Dockerを用いたGo言語の環境構築とGo Modulesを試しました。
今回はすべてのファイルを自分で作りましたが、GitでDockerfileなどの必要なファイルさえ共有できれば 、$docker-compose up コマンド1つですぐに同じ環境を構築できることが分かりました。とても便利ですね。
今後は、AWSとの連携を視野に入れつつ勉強を進めていきたいと思います。閲覧していただきありがとうございました!