380

cpanmさまざまなプロジェクトのベース イメージとして多数の Perl モジュールをインストールするために使用して、開発プロセス用の新しい Docker イメージを構築しようとしています。

Dockerfile の開発中に、cpanm一部のモジュールが正常にインストールされなかったため、失敗コードが返されます。

aptさらにいくつかのものをインストールする必要があると確信しています。

/.cpanm/work私の質問は、ログを検査するために、出力で引用されているディレクトリをどこで見つけることができるかということです。docker build一般的に、失敗したコマンドのファイル システムを調べるにはどうすればよいですか?

の編集弾丸を噛んで実行した後、find私は発見しました

/var/lib/docker/aufs/diff/3afa404e[...]/.cpanm

これは信頼できますか、それとも「ベア」コンテナを構築し、必要なものがすべて揃うまで手動で実行する方がよいでしょうか?

4

8 に答える 8

481

RUNdocker が Dockerfile からコマンドを正常に実行するたびに、イメージ ファイルシステムの新しいレイヤーがコミットされます。便利なことに、これらのレイヤー ID をイメージとして使用して、新しいコンテナーを開始できます。

次の Dockerfile を使用します。

FROM busybox
RUN echo 'foo' > /tmp/foo.txt
RUN echo 'bar' >> /tmp/foo.txt

そしてそれを構築します:

$ docker build -t so-26220957 .
Sending build context to Docker daemon 47.62 kB
Step 1/3 : FROM busybox
 ---> 00f017a8c2a6
Step 2/3 : RUN echo 'foo' > /tmp/foo.txt
 ---> Running in 4dbd01ebf27f
 ---> 044e1532c690
Removing intermediate container 4dbd01ebf27f
Step 3/3 : RUN echo 'bar' >> /tmp/foo.txt
 ---> Running in 74d81cb9d2b1
 ---> 5bd8172529c1
Removing intermediate container 74d81cb9d2b1
Successfully built 5bd8172529c1

00f017a8c2a6044e1532c690およびから新しいコンテナを開始できるようになりました5bd8172529c1

$ docker run --rm 00f017a8c2a6 cat /tmp/foo.txt
cat: /tmp/foo.txt: No such file or directory

$ docker run --rm 044e1532c690 cat /tmp/foo.txt
foo

$ docker run --rm 5bd8172529c1 cat /tmp/foo.txt
foo
bar

もちろん、シェルを起動してファイルシステムを探索し、コマンドを試すこともできます。

$ docker run --rm -it 044e1532c690 sh      
/ # ls -l /tmp
total 4
-rw-r--r--    1 root     root             4 Mar  9 19:09 foo.txt
/ # cat /tmp/foo.txt 
foo

Dockerfile コマンドの 1 つが失敗した場合、前のレイヤーの ID を探し、そのIDから作成されたコンテナーでシェルを実行する必要があります。

docker run --rm -it <id_last_working_layer> bash -il

コンテナに入ったら:

  • 失敗したコマンドを試して、問題を再現する
  • 次に、コマンドを修正してテストします
  • 最後に、固定コマンドで Dockerfile を更新します

最後の作業レイヤーから作業するのではなく、失敗した実際のレイヤーで実際に実験する必要がある場合は、Drew の回答を参照してください。

于 2014-10-06T18:38:36.287 に答える
252

一番上の答えは、失敗したコマンドの直前の状態を調べたい場合に機能します。

ただし、質問は、失敗したコンテナー自体の状態を調べる方法を尋ねます。私の状況では、失敗したコマンドは数時間かかるビルドであるため、失敗したコマンドの前に巻き戻して再度実行すると時間がかかり、あまり役に立ちません。

ここでの解決策は、失敗したコンテナーを見つけることです。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS               NAMES
6934ada98de6        42e0228751b3        "/bin/sh -c './utils/"   24 minutes ago      Exited (1) About a minute ago                       sleepy_bell

イメージにコミットします。

$ docker commit 6934ada98de6
sha256:7015687976a478e0e94b60fa496d319cdf4ec847bcd612aecf869a72336e6b83

そして、イメージを実行します [必要に応じて、bash を実行します]:

$ docker run -it 7015687976a4 [bash -il]

これで、失敗の原因となったコマンドを実行する前の時点ではなく、失敗した時点のビルドの状態を実際に確認できます。

于 2016-02-14T01:35:33.080 に答える
4

ビルドステップの失敗をデバッグするのは、実に面倒です。

私が見つけた最善の解決策は、実際の作業を行う各ステップが成功することを確認し、失敗したステップの後にチェックを追加することです。そうすれば、検査できる失敗したステップの出力を含むコミットされたレイヤーを取得できます。

行の後に例を含む Dockerfile # Run DB2 silent installer:

#
# DB2 10.5 Client Dockerfile (Part 1)
#
# Requires
#   - DB2 10.5 Client for 64bit Linux ibm_data_server_runtime_client_linuxx64_v10.5.tar.gz
#   - Response file for DB2 10.5 Client for 64bit Linux db2rtcl_nr.rsp 
#
#
# Using Ubuntu 14.04 base image as the starting point.
FROM ubuntu:14.04

MAINTAINER David Carew <carew@us.ibm.com>

# DB2 prereqs (also installing sharutils package as we use the utility uuencode to generate password - all others are required for the DB2 Client) 
RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y sharutils binutils libstdc++6:i386 libpam0g:i386 && ln -s /lib/i386-linux-gnu/libpam.so.0 /lib/libpam.so.0
RUN apt-get install -y libxml2


# Create user db2clnt
# Generate strong random password and allow sudo to root w/o password
#
RUN  \
   adduser --quiet --disabled-password -shell /bin/bash -home /home/db2clnt --gecos "DB2 Client" db2clnt && \
   echo db2clnt:`dd if=/dev/urandom bs=16 count=1 2>/dev/null | uuencode -| head -n 2 | grep -v begin | cut -b 2-10` | chgpasswd && \
   adduser db2clnt sudo && \
   echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# Install DB2
RUN mkdir /install
# Copy DB2 tarball - ADD command will expand it automatically
ADD v10.5fp9_linuxx64_rtcl.tar.gz /install/
# Copy response file
COPY  db2rtcl_nr.rsp /install/
# Run  DB2 silent installer
RUN mkdir /logs
RUN (/install/rtcl/db2setup -t /logs/trace -l /logs/log -u /install/db2rtcl_nr.rsp && touch /install/done) || /bin/true
RUN test -f /install/done || (echo ERROR-------; echo install failed, see files in container /logs directory of the last container layer; echo run docker run '<last image id>' /bin/cat /logs/trace; echo ----------)
RUN test -f /install/done

# Clean up unwanted files
RUN rm -fr /install/rtcl

# Login as db2clnt user
CMD su - db2clnt
于 2017-11-26T11:09:35.370 に答える