Docker和符号链接

raogr8fs  于 2022-11-02  发布在  Docker
关注(0)|答案(4)|浏览(174)

我有一个这样的回购协议:

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

但是,由于Docker无法处理符号链接,因此无法构建映像。我应该指出,我的项目远比这复杂,因此重构目录不是一个好的选择。我该如何处理这种情况呢?

mwyxok5s

mwyxok5s1#

坞站X1 E0 F1 X
以下是在容器中使用共享文件的一些不同方法:

构建时间

从配置映像复制(Docker构建工具包)

Docker的最新版本允许RUN步骤从命名映像或以前的构建阶段与--mount=type=bind,target=/dir,source=/dir,from=image-or-stage-name绑定挂载
为包含共享配置/文件的基本me/worker-config映像创建Dockerfile

FROM scratch
COPY config.json /config.json

构建并标记配置映像me/worker-config

docker build -t me/worker-config:latest .

在真实的构建期间挂载me/worker-config映像

RUN --mount=type=bind,target=/worker-config,source=/,from=me/worker-config:latest \
    cp /worker-config/config.json /app/config.json;

共享基本映像

为包含共享配置/文件的基本me/worker-config映像创建Dockerfile

COPY config.json /config.json

构建并标记映像me/worker-config

docker build -t me/worker-config:latest .

为您的所有worker Dockerfile源化基本me/worker-config映像

FROM me/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 /

增加映像构建上下文的范围

通过从包含共享文件和特定容器文件的父目录进行构建,在构建上下文中包含符号链接目标文件。

cd ..
docker build -f worker-a/Dockerfile .

您在Dockerfile中引用的所有源路径也必须更改,以匹配新的构建上下文:

COPY workerathing /app

变成了

COPY worker-a/workerathing /app

如果您有一个大型建置内容,使用这个方法可以让 * 所有 * 建置内容都很大,因为它们都变成共用的。它会减慢建置,特别是远端Docker建置服务器的建置。请注意,只会指涉the base of the build context中的.dockerignore档案。

可以装载卷的备用内部版本

其他致力于Dockerfile兼容性的项目可能在构建时支持卷。例如,podman build/buildah支持--volume选项,以将挂载文件从主机绑定到构建容器。

podman build --volume /project/config:/worker-config:ro,Z -t me/worker-a .

然后,构建版本可以引用已装载的卷

COPY /worker-config/config.json /app

运行时间

从命名卷装入config目录

像这样的卷只能作为目录使用,因此您不能像将文件从主机装载到容器时那样指定文件。

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

从数据容器装入config目录

同样,目录只是因为它基本上是相同的上面。这将自动复制文件从目标目录到新创建的共享卷虽然。

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
mrfwxfqh

mrfwxfqh2#

Node.js特定的解决方案

我也遇到了这个问题,我想分享另一个上面没有提到的方法,我在Dockerfile中没有使用npm link,而是使用了yalc
1.在容器中安装yalc,例如RUN npm i -g yalc
1.在Docker中构建你的库,然后运行yalc publish(如果你的共享库是私有的,添加--private标志)。这将在本地“发布”你的库。
1.在运行npm install之前,在每个通常使用npm link的存储库中运行yalc add my-lib。它将在您的Docker容器中创建一个本地.yalc文件夹,在node_modules中创建一个指向此文件夹的符号链接,并重写您的package.json以引用此文件夹,这样您就可以安全地运行install。
1.或者,如果执行两阶段构建,请确保还将.yalc文件夹复制到最终映像。
下面是一个Dockerfile示例,假设您有一个包含三个软件包的mono仓库: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"]

希望能帮上忙...

yhuiod9q

yhuiod9q3#

The docker build CLI command sends the specified directory (typically . ) as the "build context" to the Docker Engine (daemon). Instead of specifying the build context as /worker-a , specify the build context as the root directory, and use the -f argument to specify the path to the Dockerfile in one of the child directories.

docker build -f worker-a/Dockerfile .
docker build -f worker-b/Dockerfile .

You'll have to rework your Dockerfiles slightly, to point them to ../config/config.json , but that is pretty trivial to fix.
Also check out this question/answer, which I think addresses the exact same problem that you're experiencing.
How to include files outside of Docker's build context?
Hope this helps! Cheers

oxiaedzo

oxiaedzo4#

另一种解决方案是将所有的软链接升级为硬链接。

相关问题