2017-05-07

Dockerを使ったCLIツール配布

homebrewやcurl -sL {url} | shなどの/usr/local/binに置く以外にもdockerを使って配布できますよ、という備忘録。

Dockerfile

curlでインストールできるのであれば、Dockerfileを以下のように記述します。
FROM alpine:3.4

RUN apk -U add curl bash && rm -rf /var/cache/apk/*
RUN curl -sL http://install.freedom-man.com/spm | bash
ENTRYPOINT ["spm"]

Alpine Linuxは軽量Linuxで apkコマンドを使ってパッケージをインストールします。デフォルトではbashすらも入っていないので、bashとcurlをインストールしてcurl -sL方式でコンテナ側の/usr/local/binにインストールします。あとはENTRYPOINTを配列形式にすると、コマンドの記述を省略できるので以下の形式でコマンドを実行できます。

$ docker run --rm {docker_user}/{docker_repo} {引数}

コンテナ内でgolang製のCLIツールをビルドしたい場合のDockerfileはこんな感じです。

FROM golang:1.7.5-alpine
RUN apk update && \
    apk add --virtual build-dependencies build-base git curl && \
    mkdir -p src/github.com/tzmfreedom && \
    git clone https://github.com/tzmfreedom/spm src/github.com/tzmfreedom/spm && \
    cd src/github.com/tzmfreedom/spm && make deps && go install && \
    rm -rf /go/src && \
    rm -rf /var/cache/apk/* && \
    apk del build-dependencies

ENTRYPOINT ["spm"]

vendoringしていない場合、vendoringしていてvendorディレクトリがリポジトリに含まれている場合は go getするだけで良いです。vendoringしていてvendorディレクトリがリポジトリに含まれていない場合は、git cloneしてから各vendoringのツールで依存パッケージをインストールします。上記Dockerfileだとmake deps内で glide自体のインストールと glide installの実行をしています。

Alpineを使わない場合はonbuildのコンテナを使って、以下の記述をするだけでOKです(サイズが少し大きくなります)

FROM golang:1.7.5-onbuild
ENTRYPOINT ["app"]

ただし、こちらの場合もvendorディレクトリがリポジトリに無く、vendoringを効かせたい場合はglideをインストールしたりする必要があります。ローカルでbuildしてビルドしたイメージをリモートに設置するのであれば、vendorディレクトリが既にあるので、上のスクリプトのままでOKです。

ちなみにコンテナ内にバイナリを直接置くスタイルが一番イメージのサイズが少ないです(spmで7MB程度)

イメージの設置

Docker Hubを使います。Githubとリンクさせる場合は [Create Automated Build]でGithubを選択してリポジトリを作成するだけです。[Create Repository]を選択した場合は、dockerコマンドでローカルからイメージをpushします。
$ docker login
$ docker push {username}/{repo}
このエントリーをはてなブックマークに追加