Dockerfile:COPY文件夹如果存在(有条件的COPY)
Dockerfile: COPY folder if it exists (conditional COPY)
我有用于 NodeJS 应用程序的 Dockerfile,需要在容器内复制 migrations、seeds 文件夹。但问题是我们所有的应用程序都使用相同的 Dockerfile,但并非所有应用程序都使用 DB 并具有 migrations、seeds.
Docker 文件:
...
# * package json, to be able run `npm run ...`
COPY ./package.json /app/
# * migrations, seeds if they exist
COPY ./migrations/ /app/migrations/
COPY ./seeds/ /app/seeds/
...
一切正常,但如果我们没有 migrations 文件夹,我们将得到:
=> CACHED [app 4/9] COPY --from=builder /app/node_modules /app/node_modules 0.0s
=> CACHED [app 5/9] COPY --from=builder /app/dist /app/dist 0.0s
=> CACHED [app 6/9] COPY ./package.json /app/ 0.0s
=> ERROR [app 7/9] COPY ./migrations/ /app/migrations/ 0.0s
------
> [app 7/9] COPY ./migrations/ /app/migrations/:
------
failed to compute cache key: "/migrations" not found: not found
最好的方法是什么?
TL;DR;
COPY ./migration[s]/ /app/migrations/
更详细的回答
我们可以使用 glob 模式来实现这种行为,Docker 如果找不到任何有效源也不会失败,有 3 个最常用的 glob:
?
- 任意字符,不匹配空字符
*
- 任意长度的任意字符序列,匹配空字符
[abc]
- 要匹配的字符序列,就像 ?
一样,但它只匹配括号中定义的字符
所以有3种方法可以解决这个问题
COPY ./migration?/ /app/migrations/
- 也将匹配 migrationZ、migration2 等等..
COPY ./migrations*/ /app/migrations/
- 还将匹配 migrations-cool、migrations-old
COPY ./migration[s]/ /app/migrations/
- 将匹配 only migrations,因为我们使用的是匹配 1- 中的任何字符的 glob项目序列 [s]
并且除了字母“s” 什么都不能
关于 glob 的更多信息:
https://en.wikipedia.org/wiki/Glob_(programming)
作为替代解决方案,我建议您创建多个 docker 继承自公共基础图像的图像。基本图像包含相互的内容,子图像具有特定要求,如您的情况,具有 migrations 和 seeds 文件夹。
我认为在 docker 图像中使用条件不是图像的目的,因为它是为了创建一个在所有客户端之间共享的公共状态。
我有用于 NodeJS 应用程序的 Dockerfile,需要在容器内复制 migrations、seeds 文件夹。但问题是我们所有的应用程序都使用相同的 Dockerfile,但并非所有应用程序都使用 DB 并具有 migrations、seeds.
Docker 文件:
...
# * package json, to be able run `npm run ...`
COPY ./package.json /app/
# * migrations, seeds if they exist
COPY ./migrations/ /app/migrations/
COPY ./seeds/ /app/seeds/
...
一切正常,但如果我们没有 migrations 文件夹,我们将得到:
=> CACHED [app 4/9] COPY --from=builder /app/node_modules /app/node_modules 0.0s
=> CACHED [app 5/9] COPY --from=builder /app/dist /app/dist 0.0s
=> CACHED [app 6/9] COPY ./package.json /app/ 0.0s
=> ERROR [app 7/9] COPY ./migrations/ /app/migrations/ 0.0s
------
> [app 7/9] COPY ./migrations/ /app/migrations/:
------
failed to compute cache key: "/migrations" not found: not found
最好的方法是什么?
TL;DR;
COPY ./migration[s]/ /app/migrations/
更详细的回答
我们可以使用 glob 模式来实现这种行为,Docker 如果找不到任何有效源也不会失败,有 3 个最常用的 glob:
?
- 任意字符,不匹配空字符*
- 任意长度的任意字符序列,匹配空字符[abc]
- 要匹配的字符序列,就像?
一样,但它只匹配括号中定义的字符
所以有3种方法可以解决这个问题
COPY ./migration?/ /app/migrations/
- 也将匹配 migrationZ、migration2 等等..COPY ./migrations*/ /app/migrations/
- 还将匹配 migrations-cool、migrations-oldCOPY ./migration[s]/ /app/migrations/
- 将匹配 only migrations,因为我们使用的是匹配 1- 中的任何字符的 glob项目序列[s]
并且除了字母“s” 什么都不能
关于 glob 的更多信息: https://en.wikipedia.org/wiki/Glob_(programming)
作为替代解决方案,我建议您创建多个 docker 继承自公共基础图像的图像。基本图像包含相互的内容,子图像具有特定要求,如您的情况,具有 migrations 和 seeds 文件夹。
我认为在 docker 图像中使用条件不是图像的目的,因为它是为了创建一个在所有客户端之间共享的公共状态。