Github actions 使用 maven 构建 jar 并用于 docker 图像构建

Github actions build jar with maven and use for docker image building

我希望 git 推送应该触发 mvn clean package 并使用构建 jar 构建 docker 图像。 可悲的是,我在构建图像时遇到以下错误

Step 2/4 : ADD target/de-sy-file.jar de-sy-file.jar
ADD failed: stat /var/lib/docker/tmp/docker-builder601875986/target/de-sy-file.jar: no such file or directory
##[error]Process completed with exit code 1.

有人能告诉我在哪里可以找到构建的 jar 吗?

Action.yml

on:
  push:
    branches:
      - master

name: Push to Amazon ECR

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run:
        mvn clean package --file pom.xml

  deploy:
    name: Deploy
    needs: [build]
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v1

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-central-1

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: de-sy-file
        IMAGE_TAG:  latest
      run: |
        # Build a docker container and
        # push it to ECR so that it can
        # be deployed to ECS.
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

我找到了下载和上传工件的解决方案。

我的新 action.yml :

# This workflow will build and push a new container image to Amazon ECR,
# and then will deploy a new task definition to Amazon ECS, on every push
# to the master branch.
#
# To use this workflow, you will need to complete the following set-up steps:
#
# 1. Create an ECR repository to store your images.
#    For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
#    Replace the value of `ECR_REPOSITORY` in the workflow below with your repository's name.
#    Replace the value of `aws-region` in the workflow below with your repository's region.
#
# 2. Create an ECS task definition, an ECS cluster, and an ECS service.
#    For example, follow the Getting Started guide on the ECS console:
#      https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
#    Replace the values for `service` and `cluster` in the workflow below with your service and cluster names.
#
# 3. Store your ECS task definition as a JSON file in your repository.
#    The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
#    Replace the value of `task-definition` in the workflow below with your JSON file's name.
#    Replace the value of `container-name` in the workflow below with the name of the container
#    in the `containerDefinitions` section of the task definition.
#
# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
#    See the documentation for each action used below for the recommended IAM policies for this IAM user,
#    and best practices on handling the access key credentials.

on:
  push:
    branches:
      - master

name: Push to Amazon ECR

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up JDK 1.8
      uses: actions/setup-java@v1
      with:
        java-version: 1.8
    - name: Build with Maven
      run:
        mvn clean package --file pom.xml

    - uses: actions/checkout@v1

    - run: mkdir -p target/

    - run: echo hello > target/de-sy-file.jar

    - uses: actions/upload-artifact@v1
      with:
       name: de-sy-file
       path: target/

  deploy:
    name: Deploy
    needs: [build]
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v1


    - uses: actions/checkout@v1

    - uses: actions/download-artifact@v1
      with:
          name: de-sy-file
          path: target/

    - run: cat target/de-sy-file.jar
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-central-1

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: de-sy-file
        IMAGE_TAG:  latest
      run: |
        # Build a docker container and
        # push it to ECR so that it can
        # be deployed to ECS.
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

https://github.com/actions/download-artifact

我将解释一个复杂但可能不理想的解决方案。

假设我有一个 multi-module Maven 项目,看起来像这样

│
├── cluster
│   ├── Dockerfile
│   ├── pom.xml
│   ├── src
│   └── target
│
├── common
│   ├── pom.xml
│   ├── src
│   └── target
│
├── loadbalancer
│   ├── Dockerfile
│   ├── pom.xml
│   ├── src
│   └── target
│
└── pom.xml

此 Maven 项目生成两个 JAR 应用程序,一个 loadbalancer 应用程序和一个 cluster 应用程序。我想要做的是为这两个 JAR 应用程序创建两个不同的图像。

在设置我的 GitHub 操作之前,我要做的是 运行

mvn clean install
docker build -t myimage/loadbalancer:latest ./loadbalancer
docker build -t myimage/cluster_node:latest ./cluster

第一个命令将在 loadbalancer/target/cluster/target/ 中生成我的 JAR,然后我将通过构建这两个 Dockerfiles

FROM fabric8/java-alpine-openjdk11-jre
WORKDIR /usr/src/app
COPY target/cluster.jar ./cluster.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "cluster.jar"]
FROM fabric8/java-alpine-openjdk11-jre
WORKDIR /usr/src/app
COPY target/loadbalancer.jar ./loadbalancer.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "loadbalancer.jar"]

这就是您在本地计算机上所需的全部内容。

最好的部分是您可以使用 GitHub Actions 做到这一点(但可能有更好的 dockerizing Maven 项目的方法),这里是 GitHub 动作表示:

  1. 测试和构建 loadbalancer.jarcluster.jar

  2. 使用新生成的 .jars

    构建两个 Docker 图像
  3. 用两个不同的标签标记每个图像:

    一个。 latest

    b。触发此操作的提交的 8 位数字

  4. 将它们推送到新发布的 GitHub Container Registry

name: Maven test & Docker build-push

on:
  push:
    branches: [ development ]

jobs:
  build:
    
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Set SHA8
      run: echo ::set-env name=SHA8::$(git log --oneline -1 | awk '{print }')

    - name: Test SHA8
      run: echo $SHA8

    - name: Set up JDK 11
      uses: actions/setup-java@v1.4.2
      with:
        java-version: '11.0.8'

    - name: Build with Maven
      run: mvn clean install

    - name: Login to GitHub Registry Container
      uses: docker/login-action@v1
      with:
        registry: ghcr.io
        username: ${{ github.repository_owner }}
        password: ${{ secrets.CR_PAT }}

    - name: Create docker loadbalancer image
      run: docker build -t ghcr.io/myimage/loadbalancer:latest -t ghcr.io/myimage/loadbalancer:$SHA8 ./loadbalancer

    - name: Create docker cluster_node image
      run: docker build -t ghcr.io/myimage/cluster_node:latest -t ghcr.io/myimage/cluster_node:$SHA8 ./cluster

    - name: Push docker images
      run: |
        docker push ghcr.io/myimage/loadbalancer:latest
        docker push ghcr.io/myimage/loadbalancer:$SHA8
        docker push ghcr.io/myimage/cluster_node:latest
        docker push ghcr.io/myimage/cluster_node:$SHA8

工件应该已经存储在临时工作区中,因此您不必 upload/download。

#Author: Ben Francom
name: Build

#on: workflow_dispatch
on:
    push:
        branches:
            - "main"

jobs:
    build:
        name: Package & Deploy
        runs-on: ubuntu-latest
        timeout-minutes: 25
        steps:
            - name: Cancel Previous Runs
              uses: styfle/cancel-workflow-action@0.6.0
              with:
                  access_token: ${{ github.token }}

            - uses: actions/checkout@v2
            - name: Set up JDK 8
              uses: actions/setup-java@v1
              with:
                  java-version: 8

            - name: Cache local Maven repository
              uses: actions/cache@v2
              with:
                  path: ~/.m2
                  key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
                  restore-keys: |
                      ${{ runner.os }}-maven-


            - name: Maven Package
              run: mvn -B package -DskipTests -f ./pom.xml

            -   name: Configure AWS credentials

                uses: aws-actions/configure-aws-credentials@v1
                with:
                    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
                    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
                    aws-region: us-east-1

            -   name: Login to Amazon ECR
                id: login-ecr
                uses: aws-actions/amazon-ecr-login@v1

            -   name: set env
                id: vars
                run: |
                    echo ::set-output name=github_short_sha::$(echo ${GITHUB_SHA:0:7})

            -   name: Build & Push Image
                id: build-image
                env:
                    DOCKER_BUILDKIT: 1
                    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
                    ECR_REPOSITORY: app-repo
                    IMAGE_TAG: ${{ steps.vars.outputs.github_short_sha }}
                run: |
                    docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:latest -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
                    docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
                    docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
                    echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

            -   name: Fill in the new image ID for App Fargate task definition
                id: app-task-def
                uses: aws-actions/amazon-ecs-render-task-definition@v1
                with:
                    task-definition: .aws/prod-definition.json
                    container-name: prod-app-container
                    image: ${{ steps.build-image.outputs.image }}


            -   name: Deploy App Fargate Task
                uses: aws-actions/amazon-ecs-deploy-task-definition@v1
                with:
                    task-definition: ${{ steps.app-task-def.outputs.task-definition }}
                    service: prod-service
                    cluster: prod-cluster

Docker 文件

FROM openjdk:8-jdk-slim as builder
#WORKDIR build
EXPOSE 8080
RUN mkdir target
ARG JAR_FILE=./target/*.jar
COPY ${JAR_FILE} target/app.jar
ENTRYPOINT ["java","-jar","/target/app.jar"]