Search code examples
spring-bootcontinuous-integrationconcourseconcourse-pipeline

Building and pushing a docker image for a springboot application on ECR using concourse


I am building a concourse pipeline for a spring-boot service. The pipeline has two jobs (test, package-build-and-push).

The first job (test) has a single task (mvn-test-task) that will be responsible for running a maven test.

The second job has two tasks (mvn-package-task, build-image-task). The second job will only run after the first job (test) has finished. The first task (mvn-package-task) will be doing a maven package. Once the task (mvn-package-task) is finished it should copy the complete project folder with the generated target folder to the directory "concourse-demo-repo-out". This folder (concourse-demo-repo-out) then becomes the input folder for the next task (build-image-task) that will use to generate a docker image. The output will be a docker image that is placed in the directory (image).

I now need to push this image to an Amazon ECR repository. For this I am using a resource of the type docker-image (https://github.com/concourse/docker-image-resource). The problem that I am facing now is:

  1. How do I tag the image that was created, and is placed inside the image directory?
  2. How do I specify that I already have an image created to this docker image resource type, so that it uses that, tags it, and then pushes it to ECR.

My pipeline looks like this

resources:
  - name: concourse-demo-repo
    type: git
    icon: github
    source:
      branch: main
      uri: https://github.xyz.com/gzt/concourse-demo.git
      username: <my-username>
      password: <my-token>

  - name: ecr-docker-reg
    type: docker-image
    icon: docker
    source:
      aws_access_key_id: <my-aws-access-key>
      aws_secret_access_key: <my-aws-secret-key>
      repository: <my-aws-ecr-repo>

jobs:
  - name: test
    public: true
    plan:
      - get: concourse-demo-repo
        trigger: true
      - task: mvn-test-task
        file: concourse-demo-repo/ci/tasks/maven-test.yml

  - name: package-build-and-push
    public: true
    serial: true
    plan:
      - get: concourse-demo-repo
        trigger: true
        passed: [test]
      - task: mvn-package-task
        file: concourse-demo-repo/ci/tasks/maven-package.yml
      - task: build-image-task
        privileged: true # oci-build-task must run in a privileged container
        file: concourse-demo-repo/ci/tasks/build-image.yml
      - put: ecr-docker-reg
        params:
          load: image

The maven package task and script

---
platform: linux
image_resource:
  type: docker-image
  source:
    repository: maven
inputs:
  - name: concourse-demo-repo
run:
  path: /bin/sh
  args: ["./concourse-demo-repo/ci/scripts/maven-package.sh"]
outputs:
  - name: concourse-demo-repo-out
#!/bin/bash

set -e
cd concourse-demo-repo
mvn clean package
#cp -R ./target ../concourse-demo-repo-out
cp -a * ../concourse-demo-repo-out

The build image task

---
platform: linux
image_resource:
  type: registry-image
  source:
    repository: concourse/oci-build-task
inputs:
  - name: concourse-demo-repo-out
outputs:
  - name: image
params:
  CONTEXT: concourse-demo-repo-out
run:
  path: build

So finally when I run the pipeline, everything works fine, I am able to build a docker image that is placed in the image directory but I am not able to use the image as a part of "put: ecr-docker-reg".

The error that I get while running the pipeline is

selected worker: ed5d4164f835
waiting for docker to come up...
open image/image: no such file or directory

Solution

  • Consider using registry-image instead. Use this example for image resource definition where you specify the desired tag.

    Your build-image-task is analogous to the build task from the example.

    Finally, the put will look something like:

        - put: ecr-docker-reg
          params:
            image: image/image <--- but make sure this file exists, read on...
    
    

    Given that concourse complained about open image/image: no such file or directory, verify that the filename is what you expect it to be. Hijack the failed task and look inside of the image output directory:

    $ fly -t my-concourse i -j mypipeline/package-build-and-push
    
    (select the build-image-task from the list)
    
    # ls -al image/
    
    (actual filename here)
    

    👍