この記事はユアマイスター Advent Calendar 2021 10日目の記事です。
こんにちは!
Webエンジニアをしています。
南です。
最近Goの勉強をしていて、まずはじめに行ったのがGoの環境構築でした。
ローカルのマシンの環境を汚したくないというのと、他のPCでも同じ用に環境構築ができたらいいなという理由でDokcerを使って環境構築を行うことにしました。
今回は僕がGoの勉強を行う際に、行った環境構築について紹介します。
ちなみに使用するGoのバージョンは、勉強の際に最新だった1.16で環境構築を行っていきます。
また、Dockerのバージョンは3.3.1を使用しています。
ディレクトリ構成
Photo by Maksym Kaharlytskyi on Unsplash
今回行った環境構築では、次のような構成にしました。
1 2 3 4 5 6 |
docker/ docker関連のファイル src/ api/ Go関連のファイル |
元々Go側でAPI、フロント側でVueJsを使ったアプリを作ろうと思っていて、このような構成にしました。
Dockerについてはdockerディレクトリにまとめて、APIについてはsrc/apiにまとめておいた方が、管理もしやすいと思ったからです。
Goの環境構築
Photo by Josh Hild on Unsplash
では、ここから実際にGoの環境構築を行っていきます。
今回行った環境構築は以下のリポジトリから、クローン可能ですので、良かったら試してみてください。
※今回はあくまで勉強用に作った物になるため、プロダクション環境において適切かどうかは、各自お調べ頂ければと思います。
.envファイルの作成
まずはdokcer-compose.ymlなどで使っていく環境変数を、.envファイルにまとめていきます。
以下のような構成で作ってください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
VOLUMES_DRIVER=local ### Paths ################################################# # dokcerのコンテナの中でのディレクトリを指定 API_CODE_WORKDIR=/src/api # ローカル環境のディレクトリの場所を指定 API_CODE_LOCAL_PATH=../src/api ### PORT ################################################# # ローカルホストでアクセスするポートの指定 API_PORT=8000 ### VERSIONS ################################################# # 今回使用するGoのバージョンを指定。 GO_VERSION=1.16 |
docker-compose.ymlの作成
.envが作成できたら、次はdocker-compose.ymlを作っていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
version: '3' services: api: container_name: docker_go_api build: context: ./api args: - GO_VERSION=${GO_VERSION} - API_CODE_WORKDIR=${API_CODE_WORKDIR} volumes: - ${API_CODE_LOCAL_PATH}:${API_CODE_WORKDIR} ports: - ${API_PORT}:${API_PORT} tty: true |
Go用のDokcerfileの作成
docker-compose.ymlが作成できたら、次はGo用のDockerfileを作っていきます。
dockerディレクトリ内に、apiというディレクトリを作ってください。
apiというディレクトリにする理由は、docker-compose.yml内で、contextの箇所に./apiと指定しているからです。
apiというディレクトリができたら、Dockerfileを作成します。
Dockerfileの中身は、以下のように設定します。
1 2 3 4 5 6 7 8 9 10 11 |
## 使用するGoのバージョンを指定 ARG GO_VERSION=${GO_VERSION} ## コンテナ内で使用するディレクトリを指定 ARG API_CODE_WORKDIR=${API_CODE_WORKDIR} FROM golang:${GO_VERSION}-alpine RUN apk update && apk add git alpine-sdk # ワーキングディレクトリの設定 WORKDIR /src/api |
Goファイルの作成
Photo by Kelly Sikkema on Unsplash
Go用のDockerfileが作成できたら、最後にGoのファイルを作成します。
go-dockerディレクトリ内に、src/apiという階層でディレクトリを作成します。
apiのディレクトリ内で、main.goというファイルを作成します。
中身は、一旦以下のようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package main import ( "io" "log" "net/http" ) func main() { indexFunc := func(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "indexページ") } http.HandleFunc("/", indexFunc) log.Fatal(http.ListenAndServe(":8000", nil)) } |
Dockerの立ち上げ
Photo by Andy Hermawan on Unsplash
ここまでできたら、最後に以下のコマンドをdocker-compose.ymlがあるディレクトリで、叩いてみてください。
dockerが立ち上がります。
1 |
docker-compose up -d |
dockerが立ち上がったら、以下のコマンドでdokcerのコンテナの中に入りましょう。
1 2 |
## docker_go_apiの箇所は、container_nameで指定したものを指定します。 docker exec -it docker_go_api sh |
中に入ってlsコマンドを打つと以下のようになっていると思います。
1 2 3 |
/src/api # ls main.go /src/api # |
上記のように表示されたら、同じ場所で以下のコマンドを打ってGoのビルドを行って立ち上げます。
1 |
go run main.go |
コマンドをうった後に、以下のURLにアクセスします。
すると、以下のように表示されるはずです。
URL:http://localhost:8000/
画面に表示されるもの: indexページ
これでGoの環境構築は完了です。
Goファイルの中身紹介
Photo by Vladislav Klapin on Unsplash
最後に今回処理を書いている、Goファイルの中身について少し紹介します。
以下のGoファイルで行っていることは、次のようなことをしています。
1.HTTPリクエストに対するレスポンスを実装。
2.URLのパターンにマッチした際の関数をDefaultServeMuxに登録。
3.ListenAndServeを使って、HTTPサーバーを起動。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package main import ( "io" "log" "net/http" ) func main() { indexFunc := func(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "index ページ") } http.HandleFunc("/", indexFunc) log.Fatal(http.ListenAndServe(":8000", nil)) } |
HTTPリクエストに対するレスポンスを実装について
HTTPリクエストに対するレスポンスを実装については、以下の箇所で行っています。
1 2 3 |
indexFunc := func(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "index ページ") } |
ioはGoが提供している入出力用のパッケージで、その中のWriteStringというメソッドを使って文字を出力しています。
URLのパターンにマッチした際の関数をDefaultServeMuxに登録について
URLのパターンにマッチした際の関数をDefaultServeMuxに登録している処理は以下の箇所で行っています。
DefaultServeMuxは、net/httpパッケージで使用されているグローバル変数のことで、次で紹介するListenAndServeの第2引数をnilとした場合に使用されます。
以下のHandleFuncメソッドで、各パターンをDefaultServeMux内に登録します。
1 2 |
## '/'のパターンで、indexFuncの処理をDefaultServeMuxに登録。 http.HandleFunc("/", indexFunc) |
ListenAndServeを使って、HTTPサーバーを起動について
ListenAndServeを使うことで、httpパッケージのServeメソッドを呼び出します。
このメソッドの中で受け取ったHTTPリクエストに対して対応するハンドラーを返すといったことをして、レスポンスを返却しています。
ListenAndServeについては以下。
Serveメソッドについては以下に詳しく記載されています。
1 |
log.Fatal(http.ListenAndServe(":8000", nil)) |
まとめ
今回は僕がGoを勉強する際に行った環境構築について紹介しました。
この記事が同じようにGoの勉強を始めるために、環境構築について悩む人のために慣れば幸いです。
今回環境構築に使ったソースは以下から使用できますので、良かったら参考にされてみてください!