我有一个这样的回购设置:
/config
config.json
/worker-a
Dockerfile
<symlink to config.json>
/code
/worker-b
Dockerfile
<symlink to config.json>
/code
然而,构建图像失败,因为Docker无法处理符号链接。我应该提到我的项目比这复杂得多,所以重组目录不是一个很好的选择。我该如何处理这种情况?
答案 0 :(得分:39)
Docker doesn't support symlinking files outside the build context。
在容器中使用共享文件的一些不同方法。
为包含共享配置/文件的基本Dockerfile
图片创建worker-config
。
COPY config.json /config.json
构建图像并将其标记为worker-config
docker build -t worker-config:latest .
为所有工作人员worker-config
Dockerfile
图片
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
版本的公共网址中提取配置。
ADD http://somehost/config.json /
通过从包含共享文件和特定容器文件的父目录构建,在构建上下文中包含符号链接目标文件。
cd ..
docker build -f worker-a/Dockerfile .
您在Dockerfile
中引用的所有源路径也必须更改以匹配新的构建上下文:
COPY workerathing /app
变为
COPY worker-a/workerathing /app
如果您有一个大型构建上下文,则使用此方法可以使所有构建上下文变大,因为它们都会共享。它可以减慢构建速度,尤其是远程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
答案 1 :(得分:2)
docker build
CLI命令将指定目录(通常为.
)作为“构建上下文”发送到Docker Engine(守护程序)。不要将构建上下文指定为/worker-a
,而是将构建上下文指定为根目录,并使用-f
参数指定其中一个子目录中Dockerfile
的路径。 / p>
docker build -f worker-a/Dockerfile .
docker build -f worker-b/Dockerfile .
你必须稍微修改你的Dockerfiles,将它们指向../config/config.json
,但这很难解决。
同时查看此问题/答案,我认为这些问题解决了您遇到的完全相同的问题。
How to include files outside of Docker's build context?
希望这有帮助!干杯
答案 2 :(得分:0)
另一种解决方案是将所有软链接升级为硬链接。
答案 3 :(得分:0)
我也遇到了这个问题,并且想分享另一种上面没有提到的方法。我没有在npm link
中使用Dockerfile
,而是使用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
下,假设您有一个包含三个程序包的mono存储库:模型,gui和服务器,并且必须共享模型存储库并将其命名为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"]
希望有帮助...