GitHub Actions构建Docker镜像遇COPY failed错误求排查
问题背景
尝试通过GitHub Actions构建Docker镜像,工作流配置如下:
jobs: deploy-dev: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: - name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin' cache: maven - name: Build Application with Maven run: mvn clean install -DskipTests - name: Build image id: build-image env: run: | docker-compose build a-service
项目结构:
java-project/ ├─ docker-compose.yml ├─ services/ │ ├─ a/ │ │ ├─ Dockerfile │ │ ├─ pom.xml │ ├─ b/ │ │ ├─ pom.xml │ │ ├─ Dockerfile ├─ pom.xml
docker-compose.yml中a-service配置:
services: a-service: container-name: a-service build: context: ./services/a
service a的Dockerfile内容:
FROM amazoncorretto:11-alpine-jdk RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar COPY src/main/xxxx/xxxx/xxx xxxx ENTRYPOINT ["java","-jar","/app.jar"]
部署时出现错误:
Step 7/9 : COPY ${JAR_FILE} app.jar COPY failed: no source files were specified
本地构建正常,但GitHub Actions中报错,无.dockerignore文件。
可能的原因分析
1. Maven未在service a目录生成Jar包
根目录执行mvn clean install时,若父pom.xml未在<modules>节点中声明services/a子模块,Maven只会构建根模块,不会生成service a的target目录及Jar包。本地可能手动在services/a目录单独执行过mvn install,因此存在Jar包。
2. Docker构建上下文限制
docker-compose中a-service的构建上下文设为./services/a,意味着Docker构建时只能访问该目录下的文件。如果Maven将Jar包生成在根目录的target下,且未复制到services/a/target,Docker就找不到对应文件。本地可能手动完成了Jar包的复制操作,或构建时Jar包直接生成在services/a/target。
3. GitHub Actions工作流的Maven构建验证缺失
工作流中未添加步骤验证Maven构建产物的位置,无法确认Jar包是否生成、生成在哪个目录。比如可能因环境差异,GitHub Actions中Maven的构建输出路径与本地不同。
4. Checkout步骤的潜在问题
默认actions/checkout@v3的fetch-depth为1,若项目构建依赖历史提交内容,可能导致构建不完整;另外,checkout步骤的with字段为空,虽不影响常规拉取,但可补充完整配置排除风险。
解决方案建议
- 检查父pom.xml配置
确保父pom的<modules>节点包含所有子模块:
<modules> <module>services/a</module> <module>services/b</module> </modules>
- 调整Jar包路径或Docker上下文
- 方式一:在工作流中添加复制步骤,将根目录target的Jar包复制到service a的target目录:
- name: Copy Jar to service a directory run: | mkdir -p services/a/target cp target/a-service-*.jar services/a/target/ - 方式二:修改docker-compose的构建上下文为根目录,同时调整Dockerfile的COPY路径:
docker-compose.yml修改:
Dockerfile修改:services: a-service: container-name: a-service build: context: . dockerfile: services/a/DockerfileARG JAR_FILE=services/a/target/*.jar COPY ${JAR_FILE} app.jar
- 添加构建验证步骤
在Maven构建后添加目录查看步骤,确认Jar包位置:
- name: Verify build artifacts run: | ls -la target/ ls -la services/a/target/
内容的提问来源于stack exchange,提问作者boomchickawawa

