概要
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
