バニラ Python 環境 (後日アプリをインストールする予定) をインストールするために作成している Dockerfile があります。
FROM ubuntu:12.04
# required to build certain python libraries
RUN apt-get install python-dev -y
# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip
# install and configure virtualenv
RUN pip install virtualenv
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh
ビルドは最後の行まで正常に実行されますが、最後の行で次の例外が発生します。
[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
---> Running in 8b0145d2c80d
---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
---> Running in 9d2552712ddf
---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
---> Running in c13a187261ec
/bin/sh: 1: source: not found
そのディレクトリに入るとls
(前の手順がコミットされたことをテストするため)、ファイルが期待どおりに存在することがわかります。
$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh
コマンドを実行しようとすると、source
上記と同じ「見つかりません」エラーが発生します。ただし、対話型シェル セッションを実行すると、ソースは機能します。
$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]
ここからスクリプトを実行して、 などにアクセスできworkon
ますmkvirtualenv
。
調べてみたところ、当初は、Ubuntuログイン シェルとしてのbashとUbuntuシステム シェルとしてのdashの違いに問題があるようで、dash はコマンドをサポートしていませんでした。source
ただし、これに対する答えは の代わりに'.'source
を使用することのようですが、これにより Docker ランタイムが go panic 例外で爆発するだけです。
これを回避するには、Dockerfile RUN 命令からシェル スクリプトを実行する最適な方法は何ですか (Ubuntu 12.04 LTS のデフォルトのベース イメージを実行しています)。
ベストアンサー1
元の回答
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
これは、すべての Ubuntu docker ベース イメージで機能するはずです。通常、私は作成するすべての Dockerfile にこの行を追加します。
心配している傍観者による編集
コンテナ内のOSを変更したり、損傷したりすることなく、Dockerfile全体bash
で代わりに使用することの効果を得たい場合、次のようにします。sh
Dockerにあなたの意図を伝えるそれは次のように行われます:
SHELL ["/bin/bash", "-c"]
* 起こり得る損害は、 Linux の多くのスクリプト (Ubuntu の新規インストールでは
grep -rHInE '/bin/sh' /
2700 件を超える結果が返されます) が、完全な POSIX シェルを期待していることです/bin/sh
。bash シェルは、POSIX に余分な組み込み関数を加えただけのものではありません。POSIX とはまったく異なる動作をする組み込み関数 (など) があります。私は、POSIX (および、basmism を避けたと思っているので、別のシェルでテストしていないスクリプトはどれも動作するという誤解) を避けて、bashism だけを使用することを全面的に支持します。ただし、スクリプト内の適切なシェバンを使用してそれを行います。OS 全体から POSIX シェルを引き抜いて行うのではありません (Linux に付属する 2700 件を超えるスクリプトと、インストールするパッケージ内のすべてのスクリプトを検証する時間がある場合は別です)。
詳細は下記の回答をご覧ください。https://stackoverflow.com/a/45087082/117471