an odd fellow

仕事のメモ

docker multi stage buildを試す

背景

reviewdogのDockerfileについて先輩社員にレビューもらうと、dockerのmulti stage build使うと幸せになれるよと教えてもらった。

レビューをもらったDockerfileは以下。pythonのdockerイメージにgoをインストールしてからgo getでreviewdogを入れている。これをまずgoのイメージでreviewdogをgo getしてきて、pythonのイメージにコピーしてくればいいんじゃないの?という意図で言ったのだと思う。

FROM python:3.6

USER root
ENV HOME /root

# install Golang
ARG GO_VERSION=1.8.3
RUN mkdir /tmp/go && \
    cd /tmp/go && \
    curl -O -sS -L https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz && \
    tar zxf go${GO_VERSION}.linux-amd64.tar.gz && \
    mkdir /usr/local/go && \
    mv go/* /usr/local/go && \
    rm -rf /tmp/go
ENV GOPATH=${HOME}/go
ENV PATH=${PATH}:/usr/local/go/bin:${GOPATH}/bin

# install reviewdog
RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog
ENV GITHUB_API="https://github.com/api/v3/"
ARG GITHUB_API_TOKEN=""
ENV REVIEWDOG_GITHUB_API_TOKEN=${GITHUB_API_TOKEN}

# リポジトリをコンテナにマウント
ARG WORK_DIR
WORKDIR ${WORK_DIR}
ENV APP_ROOT ${WORK_DIR}
COPY . ${APP_ROOT}

# install flake8
RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming

結論

やってみた。こんな感じになった。goはバイナリに出来るので、ランタイムが不要になるのでこういうことが出来るのか。素晴らしい。golangのインストールとかGOPATHの設定がなくなっていい感じになりました。

FROM golang:latest as reviewdog
# install reviewdog
RUN go get github.com/haya14busa/reviewdog/cmd/reviewdog

# ------------------------------------------------------

FROM python:3.6

USER root
ENV HOME /root

# reviewdogの設定
COPY --from=reviewdog /go/bin/reviewdog /usr/local/bin/reviewdog
ENV GITHUB_API="https://github.com/api/v3/"
ARG GITHUB_API_TOKEN=""
ENV REVIEWDOG_GITHUB_API_TOKEN=${GITHUB_API_TOKEN}

# install flake8
RUN pip install flake8 flake8-import-order flake8-double-quotes flake8-print pep8_naming

# リポジトリをコンテナにマウント
ARG WORK_DIR
WORKDIR ${WORK_DIR}
ENV APP_ROOT ${WORK_DIR}
COPY . ${APP_ROOT}

# 自前のflake8 pluginのインストール
RUN pip install flake8_ml_batch/