私はこのように設定されたレポを持っています:
/config
config.json
/worker-a
Dockerfile
<symlink to config.json>
/code
/worker-b
Dockerfile
<symlink to config.json>
/code
ただし、Dockerはシンボリックリンクを処理できないため、イメージの構築は失敗します。私のプロジェクトはこれよりもはるかに複雑なので、ディレクトリの再構築は素晴らしい選択肢ではありません。この状況にどのように対処しますか?
Docker ビルドコンテキスト外のファイルのシンボリックリンクはサポートしていません 。
コンテナで共有ファイルを使用するためのいくつかの異なる方法。
共有構成/ファイルを含むベースworker-config
イメージのDockerfile
を作成します。
COPY config.json /config.json
イメージをビルドしてworker-config
としてタグ付けします
docker build -t worker-config:latest .
すべてのワーカーDockerfile
sのベースworker-config
イメージを取得します
FROM worker-config:latest
スクリプトを使用して、共通の構成を各ワーカーコンテナにプッシュします。
./build worker-n
#!/bin/sh
set -uex
rundir=$(readlink -f "${0%/*}")
container=$(shift)
cd "$rundir/$container"
cp ../config/config.json ./config-docker.json
docker build "$@" .
すべてのworker-n
ビルドの共通URLから構成をプルします。
ADD http://somehost/config.json /
共有ファイルと特定のコンテナファイルの両方を含む親ディレクトリからビルドすることにより、ビルドコンテキストにsymlinkターゲットファイルを含めます。
cd ..
docker build -f worker-a/Dockerfile .
Dockerfile
で参照するすべてのソースパスも、新しいビルドコンテキストに合わせて変更する必要があります。
COPY workerathing /app
になる
COPY worker-a/workerathing /app
このメソッドを使用すると、1つの大きなビルドコンテキストがある場合、すべてが共有されるため、allビルドコンテキストを大きくすることができます。特にリモートDockerビルドサーバーでは、ビルドが遅くなる可能性があります。
このようなボリュームはディレクトリとしてのみ機能するため、ホストからコンテナにファイルをマウントするときのようにファイルを指定することはできません。
docker volume create --name=worker-cfg-vol
docker run -v worker-cfg-vol:/config worker-config cp config.json /config
docker run -v worker-cfg-vol:/config:/config worker-a
繰り返しますが、ディレクトリは基本的に上記と同じです。ただし、これにより、宛先ディレクトリから新しく作成された共有ボリュームにファイルが自動的にコピーされます。
docker create --name wcc -v /config worker-config /bin/true
docker run --volumes-from wcc worker-a
docker run -v /app/config/config.json:/config.json worker-a
docker build
CLIコマンドは、指定されたディレクトリ(通常は.
)を「ビルドコンテキスト」としてDocker Engine(デーモン)に送信します。ビルドコンテキストを/worker-a
として指定する代わりに、ビルドコンテキストをルートディレクトリとして指定し、-f
引数を使用して、子ディレクトリの1つにあるDockerfile
へのパスを指定します。
docker build -f worker-a/Dockerfile .
docker build -f worker-b/Dockerfile .
../config/config.json
を指すようにDockerfileを少し修正する必要がありますが、修正するのは非常に簡単です。
また、この質問/回答も確認してください。これは、あなたが経験しているのとまったく同じ問題に対処していると思います。
お役に立てれば!乾杯
別の解決策は、すべてのソフトリンクをハードリンクにアップグレードすることです。
私もこの問題に遭遇しましたが、上記で言及されていない別の方法を共有したいと思います。 Dockerfile
でnpm link
を使用する代わりに、 yalc を使用しました。
yalc
をインストールします。 RUN npm i -g yalc
。yalc publish
を実行します(共有ライブラリがプライベートの場合は--private
フラグを追加します)。これにより、ライブラリがローカルに「公開」されます。yalc add my-lib
を実行する前に、通常npm link
を使用する各リポジトリでnpm install
を実行します。 Dockerコンテナーにローカル.yalc
フォルダーを作成し、node_modules
にDocker内でこのフォルダーへのシンボリックリンクを作成し、このフォルダーを参照するようにpackage.json
を書き換えます。インストールを安全に実行できます。.yalc
フォルダーも最終イメージに必ずコピーしてください。以下の例Dockerfile
では、3つのパッケージ(models、gui、server)を持つモノリポジトリがあり、modelsリポジトリは共有され、my-models
という名前である必要があります。
# You can access the container using:
# docker run -it my-name sh
# To start it stand-alone:
# docker run -it -p 8888:3000 my-name
FROM node:Alpine AS builder
# Install yalc globally (the apk add... line is only needed if your installation requires it)
RUN apk add --no-cache --virtual .gyp python make g++ && \
npm i -g yalc
RUN mkdir /packages && \
mkdir /packages/models && \
mkdir /packages/gui && \
mkdir /packages/server
COPY ./packages/models /packages/models
WORKDIR /packages/models
RUN npm install && \
npm run build && \
yalc publish --private
COPY ./packages/gui /packages/gui
WORKDIR /packages/gui
RUN yalc add my-models && \
npm install && \
npm run build
COPY ./packages/server /packages/server
WORKDIR /packages/server
RUN yalc add my-models && \
npm install && \
npm run build
FROM node:Alpine
RUN mkdir -p /app
COPY --from=builder /packages/server/package.json /app/package.json
COPY --from=builder /packages/server/dist /app/dist
# Make sure you copy the yalc registry too.
COPY --from=builder /packages/server/.yalc /app/.yalc
COPY --from=builder /packages/server/node_modules /app/node_modules
COPY --from=builder /packages/gui/dist /app/dist/public
WORKDIR /app
EXPOSE 3000
CMD ["node", "./dist/index.js"]
お役に立てば幸いです...