Dockerfileをbashでビルドしたい

問題点

Dockerfile に普通に RUN コマンドを書くと、/bin/sh で実行されてしまう。 これを /bin/bash で実行させようとして、/etc/passwd をいじってみたり /bin/sh/bin/bash にリンクしてみたりしたが、ディストリビューションによってはうまくいかないケースもあった。

具体的には、 Alpine Linux をベースにしてDockerfileで anyenv のインストールをさせようとしたところ、 anyenv は /bin/sh だと動かないのであった。

解決法

~
# Install anyenv
# --------------
RUN git clone https://github.com/riywo/anyenv ~/.anyenv \
    && echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc \
    && echo 'eval "$(anyenv init -)"' >> ~/.bashrc
ENV PATH /root/.anyenv/bin:$PATH
RUN exec $SHELL -l
# ↑ここでシェルがbashに切り替わる気がするが、切り替わらない。sourceでもダメ。

# Install Ruby by rbenv
# ---------------------
RUN anyenv install rbenv \
    && exec $SHELL -l \
    && rbenv install 2.2.0 \
    && rbenv global 2.2.0 \
    && rbenv rehash
# ↑anyenvがうまく実行できてない。
~
# Install anyenv
# --------------
RUN git clone https://github.com/riywo/anyenv ~/.anyenv \
    && echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bashrc \
    && echo 'eval "$(anyenv init -)"' >> ~/.bashrc
ENV PATH /root/.anyenv/bin:$PATH

# Install Ruby by rbenv
# ---------------------
RUN ["/bin/bash", "-c", " \
        source ~/.bashrc \
        && anyenv install rbenv \
        && source ~/.bashrc \
        && rbenv install 2.2.0 \
        && rbenv global 2.2.0 \
        && rbenv rehash \
    "]

というわけで上記のように、

RUN ["/bin/bash", "-c", "(bashで実行させたいコマンド)"]

とやるのが正解っぽい。 但し、サブシェル(コマンドが終わると環境が戻る)のようなので、毎 RUN ごとに source して .bashrc を読み込んでやる必要がある。

...スマートじゃない!

docker build コマンドのオプションから、ビルドに使用するシェルが指定できればいいのに・・。

確認したバージョン

  • docker 1.9.1
  • Alpine Linux 3.3