带有通配符的 Dockerfile COPY 在 GitLab 管道中失败。 "no source files were specified"
Dockerfile COPY with wildcard failing in the GitLab pipeline. "no source files were specified"
下面的 Dockerfile 在本地完美构建,但在 GitLab 管道中失败。
我本地机器和 GitLab 管道中的结果。看看在管道中我们可以看到 ls 命令的结果证明文件确实存在。
此复制命令:
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME
.
失败:
COPY failed: no source files were specified.
Docker 文件
FROM gradle:7.2-jdk11 AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/api/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle gradle.properties $APP_HOME
COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src
RUN gradle build || return 0
COPY . .
RUN gradle clean build
RUN ls $APP_HOME/build/libs/
# actual container
FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
ENV ARTIFACT_NAME=strangler-*-all.jar
ENV APP_HOME=/usr/api/
WORKDIR $APP_HOME
RUN echo ECHO
RUN echo $APP_HOME/build/libs/$ARTIFACT_NAME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME . <--------------------- FAILS HERE!!!
EXPOSE 8080
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
本地机器上的结果
bruno.carneiro@Brunos-MacBook-Pro strangler % docker build . -t test-dockerfile
[+] Building 128.0s (21/21) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 759B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim 0.7s
=> [internal] load metadata for docker.io/library/gradle:7.2-jdk11 1.7s
=> [stage-1 1/5] FROM docker.io/adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim@sha256:1618df660be143417bdf9badbda5c022cccfe37829e4967d8edb07c4042837d3 0.0s
=> [temp_build_image 1/10] FROM docker.io/library/gradle:7.2-jdk11@sha256:64a869d95a258a0a179763a320f3ffb85382214d04a9407afb1a4e485fcc00a8 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 36.48kB 0.1s
=> CACHED [temp_build_image 2/10] WORKDIR /usr/api/ 0.0s
=> CACHED [temp_build_image 3/10] COPY build.gradle settings.gradle gradle.properties /usr/api/ 0.0s
=> CACHED [temp_build_image 4/10] COPY gradle /usr/api//gradle 0.0s
=> [temp_build_image 5/10] COPY --chown=gradle:gradle . /home/gradle/src 0.1s
=> [temp_build_image 6/10] RUN chown -R gradle /home/gradle/src 0.5s
=> [temp_build_image 7/10] RUN gradle build || return 0 76.3s
=> [temp_build_image 8/10] COPY . . 0.1s
=> [temp_build_image 9/10] RUN gradle clean build 47.5s
=> [temp_build_image 10/10] RUN ls /usr/api//build/libs/ 0.5s
=> CACHED [stage-1 2/5] WORKDIR /usr/api/ 0.0s
=> CACHED [stage-1 3/5] RUN echo ECHO 0.0s
=> CACHED [stage-1 4/5] RUN echo /usr/api//build/libs/strangler-*-all.jar 0.0s
=> [stage-1 5/5] COPY --from=TEMP_BUILD_IMAGE /usr/api//build/libs/strangler-*-all.jar . 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:b6752359ac3fc50b20f275270442cd93fc27fb285c5e50430cc15ca6596c5d1d 0.0s
=> => naming to docker.io/library/test-dockerfile
GitLab 管道上的结果
[ ... ]
Step 12/21 : RUN ls $APP_HOME/build/libs/ <----------------- PROVES THE FILES EXIST
---> Running in 49ae17677df
strangler-0.1-all.jar
strangler-0.1.jar
strangler-0.1-runner.jar
Removing intermediate container 49ae17677dfa
---> 49fa966bdc46
Step 13/21 : FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
jdk-13.0.2_8_openj9-0.18.0-alpine-slim: Pulling from adoptopenjdk/openjdk13-openj9
df20fa9351a1: Already exists
f1a790472f05: Already exists
449b3bf6a04e: Already exists
6d408a52a4b1: Already exists
Digest: sha256:1618df660be143417bdf9badbda5c022cccfe37829e4967d8edb07c4042837d3
Status: Downloaded newer image for adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
---> 2b34114f0c98
Step 14/21 : ENV ARTIFACT_NAME=strangler-*-all.jar
---> Running in 393a0a6c1938
Removing intermediate container 393a0a6c1938
---> 3190a502ec30
Step 15/21 : ENV APP_HOME=/usr/api/
---> Running in abb26ef55c62
Removing intermediate container abb26ef55c62
---> 0e2eb6606643
Step 16/21 : WORKDIR $APP_HOME
---> Running in 0d6addbc0dc9
Removing intermediate container 0d6addbc0dc9
---> 1568234714b2
Step 17/21 : RUN echo ECHO
---> Running in c14f6b19e842
ECHO
Removing intermediate container c14f6b19e842
---> 25ebe041c45c
Step 18/21 : RUN echo $APP_HOME/build/libs/$ARTIFACT_NAME
---> Running in b48bbd257c92
/usr/api//build/libs/strangler-*-all.jar
Removing intermediate container b48bbd257c92
---> 9a33bb9fd38b
Step 19/21 : COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
COPY failed: no source files were specified. <---------- CANT FIND FILES
Cleaning up file based variables
00:00
ERROR: Job failed: command terminated with exit code 1
docker build
引擎有两个版本。 “经典”构建器输出 Step 13/21
行;较新的 BuildKit engine 写出 => [stage-1 5/5]
行。 Docker 的较新版本默认使用 BuildKit,但您可以使用 DOCKER_BUILDKIT
环境变量(当您 运行 docker build
时从主机明确请求(或不请求),而不是在你的 Docker 文件中)。
在您的 Docker 文件中,您实际上是在要求构建引擎在同一行上执行两种不同的处理:用其值替换环境变量引用,并将文件名与 shell glob.
ENV ARTIFACT_NAME=stranger-*-all.jar
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
如果 Docker first 将环境变量替换为其字符串表示,并且 second 进行 glob 扩展,那么这如您所愿。但是,如果它首先进行 glob 扩展,然后进行环境变量替换,那么它就不会。您看到的行为显然是两个 Docker 构建引擎以相反的顺序执行此操作。
(COPY
is silent on this point. The Environment replacement section suggests that environment variables should be replaced first. If this were a shell, the POSIX shell specification 的 Docker 文件文档表明参数 [环境变量] 替换将在路径名扩展之前发生。)
实际上,一旦将 Docker 文件构建到图像中,路径名就固定了。除非应用程序特别需要,否则设置环境变量来表示路径名通常没有好处。例如,$APP_HOME
环境变量在您的设置中根本没有使用,除了它是当前工作目录和不同图像中的路径。
有问题的 $ARTIFACT_NAME
显然出现在两个地方。不过,您可以修复最终图像中的文件名。如果你这样做,它只出现在 COPY
语句中,而且你不需要它的变量。
这将使最终的 Docker 文件:
FROM gradle:7.2-jdk11 AS TEMP_BUILD_IMAGE
...
FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
WORKDIR /usr/api
COPY --from=TEMP_BUILD_IMAGE /usr/api/build/libs/stranger-*-all.jar stranger.jar
EXPOSE 8080
CMD ["java", "-jar", "stranger.jar"]
下面的 Dockerfile 在本地完美构建,但在 GitLab 管道中失败。
我本地机器和 GitLab 管道中的结果。看看在管道中我们可以看到 ls 命令的结果证明文件确实存在。
此复制命令:
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME
.
失败:
COPY failed: no source files were specified.
Docker 文件
FROM gradle:7.2-jdk11 AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/api/
WORKDIR $APP_HOME
COPY build.gradle settings.gradle gradle.properties $APP_HOME
COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src
RUN gradle build || return 0
COPY . .
RUN gradle clean build
RUN ls $APP_HOME/build/libs/
# actual container
FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
ENV ARTIFACT_NAME=strangler-*-all.jar
ENV APP_HOME=/usr/api/
WORKDIR $APP_HOME
RUN echo ECHO
RUN echo $APP_HOME/build/libs/$ARTIFACT_NAME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME . <--------------------- FAILS HERE!!!
EXPOSE 8080
ENTRYPOINT exec java -jar ${ARTIFACT_NAME}
本地机器上的结果
bruno.carneiro@Brunos-MacBook-Pro strangler % docker build . -t test-dockerfile
[+] Building 128.0s (21/21) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 759B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim 0.7s
=> [internal] load metadata for docker.io/library/gradle:7.2-jdk11 1.7s
=> [stage-1 1/5] FROM docker.io/adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim@sha256:1618df660be143417bdf9badbda5c022cccfe37829e4967d8edb07c4042837d3 0.0s
=> [temp_build_image 1/10] FROM docker.io/library/gradle:7.2-jdk11@sha256:64a869d95a258a0a179763a320f3ffb85382214d04a9407afb1a4e485fcc00a8 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 36.48kB 0.1s
=> CACHED [temp_build_image 2/10] WORKDIR /usr/api/ 0.0s
=> CACHED [temp_build_image 3/10] COPY build.gradle settings.gradle gradle.properties /usr/api/ 0.0s
=> CACHED [temp_build_image 4/10] COPY gradle /usr/api//gradle 0.0s
=> [temp_build_image 5/10] COPY --chown=gradle:gradle . /home/gradle/src 0.1s
=> [temp_build_image 6/10] RUN chown -R gradle /home/gradle/src 0.5s
=> [temp_build_image 7/10] RUN gradle build || return 0 76.3s
=> [temp_build_image 8/10] COPY . . 0.1s
=> [temp_build_image 9/10] RUN gradle clean build 47.5s
=> [temp_build_image 10/10] RUN ls /usr/api//build/libs/ 0.5s
=> CACHED [stage-1 2/5] WORKDIR /usr/api/ 0.0s
=> CACHED [stage-1 3/5] RUN echo ECHO 0.0s
=> CACHED [stage-1 4/5] RUN echo /usr/api//build/libs/strangler-*-all.jar 0.0s
=> [stage-1 5/5] COPY --from=TEMP_BUILD_IMAGE /usr/api//build/libs/strangler-*-all.jar . 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:b6752359ac3fc50b20f275270442cd93fc27fb285c5e50430cc15ca6596c5d1d 0.0s
=> => naming to docker.io/library/test-dockerfile
GitLab 管道上的结果
[ ... ]
Step 12/21 : RUN ls $APP_HOME/build/libs/ <----------------- PROVES THE FILES EXIST
---> Running in 49ae17677df
strangler-0.1-all.jar
strangler-0.1.jar
strangler-0.1-runner.jar
Removing intermediate container 49ae17677dfa
---> 49fa966bdc46
Step 13/21 : FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
jdk-13.0.2_8_openj9-0.18.0-alpine-slim: Pulling from adoptopenjdk/openjdk13-openj9
df20fa9351a1: Already exists
f1a790472f05: Already exists
449b3bf6a04e: Already exists
6d408a52a4b1: Already exists
Digest: sha256:1618df660be143417bdf9badbda5c022cccfe37829e4967d8edb07c4042837d3
Status: Downloaded newer image for adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
---> 2b34114f0c98
Step 14/21 : ENV ARTIFACT_NAME=strangler-*-all.jar
---> Running in 393a0a6c1938
Removing intermediate container 393a0a6c1938
---> 3190a502ec30
Step 15/21 : ENV APP_HOME=/usr/api/
---> Running in abb26ef55c62
Removing intermediate container abb26ef55c62
---> 0e2eb6606643
Step 16/21 : WORKDIR $APP_HOME
---> Running in 0d6addbc0dc9
Removing intermediate container 0d6addbc0dc9
---> 1568234714b2
Step 17/21 : RUN echo ECHO
---> Running in c14f6b19e842
ECHO
Removing intermediate container c14f6b19e842
---> 25ebe041c45c
Step 18/21 : RUN echo $APP_HOME/build/libs/$ARTIFACT_NAME
---> Running in b48bbd257c92
/usr/api//build/libs/strangler-*-all.jar
Removing intermediate container b48bbd257c92
---> 9a33bb9fd38b
Step 19/21 : COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
COPY failed: no source files were specified. <---------- CANT FIND FILES
Cleaning up file based variables
00:00
ERROR: Job failed: command terminated with exit code 1
docker build
引擎有两个版本。 “经典”构建器输出 Step 13/21
行;较新的 BuildKit engine 写出 => [stage-1 5/5]
行。 Docker 的较新版本默认使用 BuildKit,但您可以使用 DOCKER_BUILDKIT
环境变量(当您 运行 docker build
时从主机明确请求(或不请求),而不是在你的 Docker 文件中)。
在您的 Docker 文件中,您实际上是在要求构建引擎在同一行上执行两种不同的处理:用其值替换环境变量引用,并将文件名与 shell glob.
ENV ARTIFACT_NAME=stranger-*-all.jar
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
如果 Docker first 将环境变量替换为其字符串表示,并且 second 进行 glob 扩展,那么这如您所愿。但是,如果它首先进行 glob 扩展,然后进行环境变量替换,那么它就不会。您看到的行为显然是两个 Docker 构建引擎以相反的顺序执行此操作。
(COPY
is silent on this point. The Environment replacement section suggests that environment variables should be replaced first. If this were a shell, the POSIX shell specification 的 Docker 文件文档表明参数 [环境变量] 替换将在路径名扩展之前发生。)
实际上,一旦将 Docker 文件构建到图像中,路径名就固定了。除非应用程序特别需要,否则设置环境变量来表示路径名通常没有好处。例如,$APP_HOME
环境变量在您的设置中根本没有使用,除了它是当前工作目录和不同图像中的路径。
有问题的 $ARTIFACT_NAME
显然出现在两个地方。不过,您可以修复最终图像中的文件名。如果你这样做,它只出现在 COPY
语句中,而且你不需要它的变量。
这将使最终的 Docker 文件:
FROM gradle:7.2-jdk11 AS TEMP_BUILD_IMAGE
...
FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
WORKDIR /usr/api
COPY --from=TEMP_BUILD_IMAGE /usr/api/build/libs/stranger-*-all.jar stranger.jar
EXPOSE 8080
CMD ["java", "-jar", "stranger.jar"]