web-dev-qa-db-ja.com

globパターンを使用したDocker COPYファイル?

Yarnが管理するmonorepoがあります。Dockerキャッシュレイヤーを利用してビルドを高速化したいので、最初にpackage.jsonおよびyarn.lockファイル、実行yarn installそして、残りのファイルをコピーします。

これは私のレポ構造です:

packages/one/package.json
packages/one/index.js
packages/two/package.json
packages/two/index.js
package.json
yarn.lock

そして、これはDockerfileの関心のある部分です:

COPY package.json .
COPY yarn.lock .
COPY packages/**/package.json ./
RUN yarn install --pure-lockfile
COPY . .

問題は、3番目のCOPYコマンドが何もコピーしないことです。どのように期待される結果を達成できますか?

11
Fez Vrasta

@FezVrastaのコメントを私の 最初の回答 にフォローアップするために、Dockerfileに関係するすべてのサブディレクトリを列挙できないが、Dockerを利用するためにすべてのファイルを2ステップでコピーしたい場合キャッシュ機能の場合、次の回避策を試すことができます。

  • 必要なpackage.jsonファイルを同様の階層で構築された別のディレクトリ(たとえば、.deps/)にコピーするラッパースクリプト(bashなど)を作成し、docker build …を呼び出します
  • 事前に別のディレクトリをコピー(および名前変更)するようにDockerfileを調整し、yarn install --pure-lockfile…を呼び出します

すべてをまとめると、次のファイルにつながる可能性があります。

### ./build.bash ###
#!/bin/bash

tag=copy-example:latest

rm -f -r .deps  # optional, to be sure that there is
# no extraneous "package.json" from a previous build

find . -type d \( -path \*/.deps \) -Prune -o \
  -type f \( -name "package.json" \) \
  -exec bash -c 'dest=".deps/$1" && \
    mkdir -p -- "$(dirname "$dest")" && \
    cp -av -- "$1" "$dest"' bash '{}' \;
# instead of mkdir + cp, you may also want to use
# rsync if it is available in your environment...

Sudo docker build -t "$tag" .

そして

### ./Dockerfile ###
FROM ...

WORKDIR /usr/src/app

# COPY package.json .  # subsumed by the following command
COPY .deps .
# and not "COPY .deps .deps", to avoid doing an extra "mv"
COPY yarn.lock .
RUN yarn install --pure-lockfile

COPY . .
# Notice that "COPY . ." will also copy the ".deps" folder; this is
# maybe a minor issue, but it could be avoided by passing more explicit
# paths than just "." (or by adapting the Dockerfile and the script and
# putting them in the parent folder of the Yarn application itself...)
7
ErikMD

で説明したように、COPY <src> <dest> の公式Dockerfileリファレンス

COPY命令は、<src>から新しいファイルまたはディレクトリをコピーし、パス<dest>でコンテナのファイルシステムに追加します。

あなたの場合

それぞれにワイルドカードを含めることができ、Goのfilepath.Matchルールを使用してマッチングが行われます。

これは ルール です。次のものが含まれます。

「*」は、非区切り文字の任意のシーケンスに一致します

したがって、パターンで*の代わりに**を使用するようにしてください。

5
v.karbovnichy

上記の私のコメントで概説したように、同じ名前のファイルを含む複数のサブフォルダーを指定するために、グロブでCOPYディレクティブを使用しても機能しません。しかし、簡単な解決策は、次のように記述することにより、サブフォルダーのパスをハードコーディングすることです。

# ...
WORKDIR /usr/src/app
COPY package.json .
COPY yarn.lock .
COPY packages/one/package.json packages/one/
COPY packages/two/package.json packages/two/
RUN yarn install --pure-lockfile
COPY . .
# ...

COPYディレクティブが宛先フォルダーの作成を処理することを思い出します(つまり、no need to RUN mkdir -p packages/one とか、ぐらい)

0
ErikMD