GitHub Actions中Docker构建失败:mvn package数据库连接异常
问题描述
我想把项目容器化后部署到Docker Hub,但在GitHub Actions的构建流程里遇到了问题。我用的是mr-smithers-excellent/docker-build-push@v5工具来处理Docker操作。
构建时抛出如下错误:
#14 ERROR: process "/bin/sh -c mvn package" did not complete successfully: exit code: 1 ------ > [build 5/5] RUN mvn package: Error: ERROR] Error: ERROR] Please refer to /target/surefire-reports for the individual test results. Error: ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream. Error: ERROR] -> [Help 1] Error: ERROR] Error: ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. Error: ERROR] Re-run Maven using the -X switch to enable full debug logging. Error: ERROR] Error: ERROR] For more information about the errors and possible solutions, please read the following articles: Error: ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException ------ Dockerfile:12 -------------------- 10 | 11 | # Build the project and create the executable JAR 12 | >>> RUN mvn package 13 | 14 | # Stage 2: Run stage -------------------- ERROR: failed to solve: process "/bin/sh -c mvn package" did not complete successfully: exit code: 1 Error: Command failed: docker build -f Dockerfile -t docker.io/***/bookdelivery:latest .
补充错误信息:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
附上项目的Dockerfile、GitHub Actions工作流文件:
Dockerfile内容:
# Stage 1: Build stage FROM maven:3.8.4-openjdk-17-slim AS build # Copy Maven files for dependency resolution COPY pom.xml ./ COPY .mvn .mvn # Copy application source code COPY src src # Build the project and create the executable JAR RUN mvn package # Stage 2: Run stage FROM openjdk:17-jdk-slim # Set working directory WORKDIR bookdelivery # Copy the JAR file from the build stage COPY --from=build target/*.jar bookdelivery.jar # Expose port 1221 EXPOSE 1221 # Set the entrypoint command for running the application ENTRYPOINT ["java", "-jar", "bookdelivery.jar"]
GitHub Actions工作流文件内容:
name: CI/CD Pipeline ## The following codes trigger the pipeline when the code is pushed on the main branch. on: push: branches: [main] jobs: test: name: Unit Test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'maven' - name: Build with Maven run: mvn -B package --file pom.xml - name: Cache Maven packages uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Run Tests run: mvn -B test build-and-push: name: Build and Push runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'maven' - name: Build with Maven run: mvn -B package --file pom.xml - name: Dockerize & Push Docker Image uses: mr-smithers-excellent/docker-build-push@v5 with: image: noyandocker/bookdelivery tags: latest registry: docker.io dockerfile: Dockerfile username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
解决方案
核心问题分析
Maven执行package时会自动运行测试用例,而测试代码尝试连接MySQL数据库,但Docker构建环境里没有启动对应的MySQL服务,导致连接失败,进而触发构建终止。
方案1:构建时跳过测试用例
既然你的工作流已经单独设置了Unit Test job执行测试,Docker构建阶段完全可以跳过测试,避免重复执行且无需依赖数据库。
修改Dockerfile中的RUN mvn package为:
RUN mvn package -DskipTests
或者更彻底地跳过测试插件的执行:
RUN mvn package -Dmaven.test.skip=true
方案2:在GitHub Actions中启动MySQL服务完成测试
如果必须在构建环节运行测试,推荐在build-and-push job中先启动MySQL服务,完成Maven构建后再制作镜像,避免在Docker内部处理数据库依赖。
优化后的build-and-push job示例:
build-and-push: name: Build and Push runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: your-root-pwd MYSQL_DATABASE: your-db-name MYSQL_USER: your-db-user MYSQL_PASSWORD: your-db-pwd ports: - 3306:3306 options: >- --health-cmd "mysqladmin ping -h localhost" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'maven' - name: Build with Maven (含测试) run: mvn -B package --file pom.xml env: DB_URL: jdbc:mysql://localhost:3306/your-db-name?useSSL=false&serverTimezone=UTC DB_USER: your-db-user DB_PASSWORD: your-db-pwd - name: Dockerize & Push Docker Image uses: mr-smithers-excellent/docker-build-push@v5 with: image: noyandocker/bookdelivery tags: latest registry: docker.io dockerfile: Dockerfile username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
同时简化Dockerfile,直接复制job中构建好的JAR:
FROM openjdk:17-jdk-slim WORKDIR bookdelivery COPY target/*.jar bookdelivery.jar EXPOSE 1221 ENTRYPOINT ["java", "-jar", "bookdelivery.jar"]
方案3:优化工作流,避免重复构建
当前工作流中test和build-and-push都执行了mvn package,属于重复工作。可以让build-and-push依赖test job,复用已构建好的JAR文件,减少资源消耗。
修改后的工作流示例:
name: CI/CD Pipeline on: push: branches: [main] jobs: test: name: Unit Test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: java-version: '17' distribution: 'temurin' cache: 'maven' - name: Cache Maven packages uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Build with Maven and run tests run: mvn -B package --file pom.xml - name: Upload built JAR uses: actions/upload-artifact@v3 with: name: app-jar path: target/*.jar build-and-push: name: Build and Push runs-on: ubuntu-latest needs: test steps: - name: Checkout code uses: actions/checkout@v3 - name: Download built JAR uses: actions/download-artifact@v3 with: name: app-jar path: target/ - name: Dockerize & Push Docker Image uses: mr-smithers-excellent/docker-build-push@v5 with: image: noyandocker/bookdelivery tags: latest registry: docker.io dockerfile: Dockerfile username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
同时使用方案2中的简化版Dockerfile即可。
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

