Golangのウェブサーバーで静的サイトを配信する


プロダクションではない環境でwebサイトのサーバーが欲しかった時、nginxやapacheではなくgolangで作って見ようとした時の覚書。

kubernetes上に静的サイト配信サーバーをgoで立ててみました。

Golangのnet/http

静的ファイルはGatsbyのスターターをbuildしたものをテストとして起き、main.goと同じ階層にpublicフォルダをコピペ。

public
  -static
    |- page-2
 	| -xxx.img
  -index.html
  -xxxx.js
  -xxxxxx.css
main.go

goはnet/httpパッケージでシンプルに。

package main

import (
  "log"
  "net/http"
)

func main() {
  http.Handle("/", http.FileServer(http.Dir("public")))
    log.Fatal(http.ListenAndServe(":8080", nil))
 }

http://localhost:8080

にアクセスした時、main.go同階層のpublic直下のファイルを返します。サブディレクトリのファイルやindex.htmlなどの配信をどう設定すれば良いのか全然わからず、変に難しく考えてここで数時間ハマってしまいました(1つ1つルート書いていたり)

静的ファイル返すだけならこれで動きました。動作確認後にイメージをビルドします。Golangはdockerのmulti stage buildを使って恐ろしく軽量化したイメージを作成できます

イメージの作成

参考:Create the smallest and secured golang docker image based on scratch

FROM golang:1.11.2-alpine3.8 AS builder
COPY . $GOPATH/src/mypackage/myapp/
WORKDIR $GOPATH/src/mypackage/myapp/
RUN go get -d -v
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o /go/bin/api


FROM scratch
COPY --from=builder /go/bin/api /go/bin/api
COPY ./public /public
ENTRYPOINT ["/go/bin/api"]

docker buildしてイメージの完成です。最終イメージサイズは 7.75MB。小さくて素晴らしい。 dockerとgoはとても相性が良いように感じます。