概要
golangで作ったAPIをDocker上で動かします。
作ったAPIについて: GolangでシンプルなRESTful APIを作ってみた
サンプルはここ
Dockerfileを用意する
FROM golang:latest
WORKDIR /app
ADD . /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w" -installsuffix cgo -o hello main.go
CMD ["./hello"]
Docker Compose ファイルを用意する
docker-compose.yml
version: "3.1"
services:
api:
build: .
ports:
- 1323:1323
environment:
DATA_SOURCE_NAME: root:root@tcp(db:3306)/sample
PORT: :1323
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: sample
volumes:
- ./migration:/docker-entrypoint-initdb.d
ports:
- "3306:3306"
起動
コンテナ作成に必要なファイルは揃ったのでbuildして起動する
$ docker-compose up --build -d
イメージが作られているか確認する
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld_api latest eaa02e55c990 11 seconds ago 908MB
実行できているか確認する
$ curl http://127.0.0.1:1323/users/1
{"ID":1,"Name":"suzuki"}
イメージサイズを小さくする
イメージサイズを抑えるためにalpineを使う
multi stage buildという機能があるので、それを使う
次のようにFROMが2つあるようにし、中間ステージのものに対してはas builderのように名前をつけておく
FROM golang:alpine as builder
WORKDIR /app
ADD . /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w" -installsuffix cgo -o hello main.go
FROM alpine:latest
COPY --from=builder /app/hello /bin/hello
CMD ["/bin/hello"]
buildし、imageを確認する
$ docker-compose build
...
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld_api latest 0dada9b8827e 25 seconds ago 12.2MB
908MB→12.2MBに!
約98.6%の削減!!
オマケ
さらにイメージを小さくする
scratchという何も含まれないイメージを元に、静的リンクしたバイナリを配置する
※ 使うときに証明書、タイムゾーン等に気をつけないといけない
参考) GoとDockerでscratchを使うときに気をつけること
FROM golang:alpine as builder
WORKDIR /app
ADD . /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w" -installsuffix cgo -o hello main.go
FROM scratch
COPY --from=builder /app/hello /bin/hello
CMD ["/bin/hello"]
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld_api latest d96e6246972c 8 seconds ago 6.6MB
upxを使ってさらに小さくする
FROM golang:alpine as builder
RUN apk --update add upx
WORKDIR /app
ADD . /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-s -w" -installsuffix cgo -o hello main.go &&\
upx /app/hello
FROM scratch
COPY --from=builder /app/hello /bin/hello
CMD ["/bin/hello"]
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld_api latest 0b7c833abf5c 9 seconds ago 2.58MB
イメージサイズ | 1つ上からの削減率 | golangからの削減率 | |
---|---|---|---|
golang | 908MB | - | - |
alpine | 12.2MB | 98.6% | 98.6% |
scratch | 6.6MB | 45.9% | 99.2% |
scratch & upx | 2.58MB | 60.9% | 99.7% |
めっちゃ小さくなったw