2016-12-01 10 views
7

内の文字列に私はトラブルDockerfileの変数を作成し、使用を持っています - 私は、このコマンドでDockerfileを通じてドッカーイメージを構築:はドッカー

$ docker build --build-arg s=scripts/a.sh -t a . 

(だから私は--build-使用しているため、引数、$ sがDockerfileで利用可能な引数、およびこの部分の作品となります)

Dockerfileはそうのようなものです:

ARG s 

RUN echo $s 

RUN useradd -ms /bin/bash newuser 

USER newuser 
WORKDIR /home/newuser 

ENV fn=$(filename $s) # fails on this line 

COPY $s . 

ENTRYPOINT ["/bin/bash", "/home/newuser/$fn"] 

私が持っている問題は、ドッカービルドがfailinされていることですgを上に示した線上に置く。私はこれまでその行を変更した場合

Error response from daemon: Syntax error - can't find = in "$s)". Must be of the form: name=value 

は:

Error: Command failed: docker build --build-arg s=scripts/a.sh -t a . 
The command '/bin/sh -c fn=$(filename $s)' returned a non-zero code: 127 

誰でも内部変数を作成します

  1. への正しい方法を知っている:

    RUN fn=$(filename $s) 
    

    私はこのエラーを取得しますドッカーファイル

  2. その変数と
  3. 使用文字列補間私はそうのようなENTRYPOINT引数に変数を参照できるように:

    ENTRYPOINT [ "/ binに/ bashの"、 "/ホーム/ NEWUSER/$のVAR"]

私はこれを行う場合でも:私はENTRYPOINTの「非JSON」バージョンを使用していていても

ARG s 

ARG sname 

RUN echo $s   # works as expected 
RUN echo $sname  # works as expected 

RUN useradd -ms /bin/bash newuser 

USER newuser 
WORKDIR /home/newuser 


COPY $s . # works as expected (I believe) 

ENTRYPOINT /bin/bash /home/newuser/$sname # does not work as expected 

を、まだ$sname変数の値をピックアップしていないようです。

答えて

10

ENTRYPOINTに変数を使用しないでください。それはやりにくく、何が起こっているのかを深く理解する必要があります。そしてそれは偶然にそれを壊すのは簡単です。次のいずれかを考慮してください。

開始スクリプトに既知の名前のリンクを作成します。

RUN ln -s /home/newuser/$sname /home/newuser/docker_entrypoint.sh 
ENTRYPOINT ["/home/newuser/docker_entrypoint.sh"] 

または必要なものを実行するスタンドアロンのエントリポイントスクリプトを作成します。

しかし、あなたの質問の解決方法とその理由を知りたければ、読んでください。

最初にいくつかの定義。

利用いただけ環境変数でありますそれらの環境変数を直接サポートするdockerfile命令のリストを参照してください。これはあなたが言ったようにCOPYが "変数を拾う"の理由です。

RUNENTRYPOINTもありません。どのように機能するのですか?

ドキュメントを詳しく調べる必要があります。最初RUNhttps://docs.docker.com/engine/reference/builder/#run)。 2つの形式があります。最初のコマンドはシェルを通してコマンドを実行し、このシェルはビルド時の環境変数にアクセスできます。

# this works because it is called as /bin/sh -c 'echo $sname' 
# the /bin/sh replace $sname for you  
RUN echo $sname 

# this does NOT work. There is no shell process to do $sname replacement 
# for you 
RUN ["echo", "$sname"] 

同じことが唯一の実行時変数を除いてENTRYPOINTCMDに適用されるコンテナの起動時に利用できます。

# first you need to make some runtime variable from builtime one 
ENV sname $sname 

# Then you can use it during container runtime 
# docker runs `/bin/sh -c '/bin/bash /home/newuser/$sname'` for you 
# and this `/bin/sh` proces interprets `$sname` 
ENTRYPOINT /bin/bash /home/newuser/$sname 

# but this does NOT work. There is no process to interpolate `$sname` 
# docker runs what you describe. 
ENTRYPOINT ["/bin/bash", "/home/newuser/$sname"] 

編集2017年4月3日:私は他の回答やコメントから感じる混乱を避けるために、ドッキングウィンドウのドキュメンテーションとわずかなrewordingに更新されたリンク。

+0

なぜ、ビルド時の引数であるENTRYPOINT引数に補間に使用できるビルド時の引数ではないのですか? ? Dockerfileで使用する変数を探していたので、外部のテンプレートツールを使用せずに、同じ文字列をコピーして貼り付ける必要はありません。 この機能が矛盾していると、なぜこの機能が追加されたのか不思議です。 – pdxleif

+0

この質問は、ドッカーチームに指摘する必要があります。私は再びARGを加えたPRを見なければならないが、私の記憶が正しければ、この可能性について議論さえしなかった。ドッカーの開発者はGitHubで非常に積極的です。 – Villlem

1

私は@Villemに答えを求めましたが、彼の答えははっきりとしていますが、以下のように動作します(安定した解決策ではありません)。彼の答えは基本的に、この答えはそれを行うには良い方法ではないことを言っている:COPYコマンドはARGを経由して宣言された変数を拾っなぜ

ARG s   # passed in via --build-arg s=foo 
ARG sname  # passed in via --build-arg sname=bar 

RUN echo $s  
RUN echo $sname 

ENV sname $sname # this is the key part 

RUN useradd -ms /bin/bash newuser 

USER newuser 
WORKDIR /home/newuser 

COPY $s . 

ENTRYPOINT /bin/bash /home/newuser/$sname # works, but is not stable! 

は私に聞かないでください、しかしENTRYPOINTコマンドはをしていることはARGで宣言された変数を受け取りますが、ENVで宣言された変数のみを受け取ります。少なくとも、これが当てはまるようです。

+1

恐らく 'COPY'(と' ADD'?)は場面の背後で 'cp'コマンドを実行し、' cp'に引数を残してエスケープしてbash変数を拡張できるようにしていますか? – pdxleif

+0

あなたの問題はhttps://github.com/moby/moby/issues/18492に関連していると思います – ygk