web-dev-qa-db-ja.com

Dockerとシンボリックリンク

私はこのように設定されたレポを持っています:

/config
   config.json
/worker-a
   Dockerfile
   <symlink to config.json>
   /code
/worker-b
   Dockerfile
   <symlink to config.json>
   /code

ただし、Dockerはシンボリックリンクを処理できないため、イメージの構築は失敗します。私のプロジェクトはこれよりもはるかに複雑なので、ディレクトリの再構築は素晴らしい選択肢ではありません。この状況にどのように対処しますか?

28
Chris B.

Docker ビルドコンテキスト外のファイルのシンボリックリンクはサポートしていません

コンテナで共有ファイルを使用するためのいくつかの異なる方法。

基本画像を共有する

共有構成/ファイルを含むベースworker-configイメージのDockerfileを作成します。

COPY config.json /config.json

イメージをビルドしてworker-configとしてタグ付けします

docker build -t worker-config:latest .

すべてのワーカーDockerfilesのベース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 "$@" .

URLからビルド

すべての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
42
Matt

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を少し修正する必要がありますが、修正するのは非常に簡単です。

また、この質問/回答も確認してください。これは、あなたが経験しているのとまったく同じ問題に対処していると思います。

Dockerのビルドコンテキスト以外のファイルを含める方法

お役に立てれば!乾杯

2
Trevor Sullivan

別の解決策は、すべてのソフトリンクをハードリンクにアップグレードすることです。

1
Benjamin Pastel

私もこの問題に遭遇しましたが、上記で言及されていない別の方法を共有したいと思います。 Dockerfilenpm linkを使用する代わりに、 yalc を使用しました。

  1. コンテナにyalcをインストールします。 RUN npm i -g yalc
  2. ライブラリをDockerでビルドし、yalc publishを実行します(共有ライブラリがプライベートの場合は--privateフラグを追加します)。これにより、ライブラリがローカルに「公開」されます。
  3. yalc add my-libを実行する前に、通常npm linkを使用する各リポジトリでnpm installを実行します。 Dockerコンテナーにローカル.yalcフォルダーを作成し、node_modulesにDocker内でこのフォルダーへのシンボリックリンクを作成し、このフォルダーを参照するようにpackage.jsonを書き換えます。インストールを安全に実行できます。
  4. 必要に応じて、2段階のビルドを行う場合は、.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"]

お役に立てば幸いです...

0
Erik Vullings