How to pull a private docker image from AWS ECR to use with the Testcontainers library in Java/Kotlin?
Asked Answered
S

1

6

I am trying to programmatically create and spin up a Testcontainers GenericContainer from a docker image hosted in a private AWS ECR repository. This will be used for automated integration tests, will be run locally and within CICD pipelines. I know I need to authenticate to pull down the image but it is not clear to me how best to get and pass authentication information from AWS to the Testcontainers context. I've read over the Testcontainers documentation but have not found details on how to authenticate to a private docker container repository.

Code I have so far is:

import org.testcontainers.containers.GenericContainer
import org.testcontainers.utility.DockerImageName

const val imageName = "<account>.dkr.ecr.<region>.amazonaws.com/<imageName>:<version>"
val testContainer = GenericContainer(DockerImageName.parse(imageName))
testContainer.start()

Of course, this gives an error:

at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
    at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:269)
    at java.base/java.lang.Thread.run(Thread.java:833)
com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"Head \"https://<account>.dkr.ecr.<region>.amazonaws.com/v2/<imageName>/manifests/<version>\": no basic auth credentials"}

So far I have found Testcontainers to be intuitive to use for all things, but this problem has got me stumped. How does one use Testcontainers with private AWS ECR repositories?

Shikoku answered 19/2, 2022 at 17:18 Comment(5)
This issue on GitHub didn't provide any help? What have you tried so far to pass the ECR credentials?Editor
I've been searching for the exact same answer. Looking into LocalStack now...Neoma
I've stumbled upon the same issue, have you happened to find a solution for that?Vaporish
@MarkBramnik I ended up using a GitHub action to pull the docker image for the CICD pipelines, so it was found local when running the testing suite. And for running local I had to pull the image in advance with AWS cli. So, in short, not really, but did find a workaround.Shikoku
Same issue. Even though all the images are pulled from ECR to local build instance, testcontainers still pulls from remote registry: Found Docker environment with local Unix socket (unix:///var/run/docker.sock) ERROR com.github.dockerjava.api.async.ResultCallbackTemplate -- Error during callback com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"toomanyrequests: You have reached your pull rate limit.Pinson
E
0

Introduction

Hello.

Below steps work at least for (Ubuntu + testcontainers:1.19.3).
Do not know if it is optimal approach but works well for me.

By default, to pull the images the testcontainers use DefaultPullPolicy:

package org.testcontainers.images;

....

/**
 * The default imagePullPolicy, which pulls the image from a remote repository only if it does not exist locally
 */
@Slf4j
@ToString
class DefaultPullPolicy extends AbstractImagePullPolicy {

    @Override
    protected boolean shouldPullCached(DockerImageName imageName, ImageData localImageData) {
        return false;
    }
}

As stated above, it tries to fetch the images ONLY IF you do not have them locally.

Run Locally

So to run tests locally that use private AWS ECR images via testcontainers you can do 2 things:

  1. Fetch them manually upfront.
  2. Or You can login to AWS using AWS CLI installed on you computer:
aws ecr get-login-password --region ${your_region} | \
docker login --username AWS --password-stdin ${your_ecr_registry}

And run the tests in standard way e.g. ./mvnw clean test. Then if image is not accessible locally then testcontainers will pull it for you. Of course your user must have appropriate rights in ECR.

Run on Github Actions

Then to run it on e.g GitHub Actions you don't have to change anything:

    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ECR_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_ECR_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

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

      - name: Setup Maven Action
        uses: s4u/[email protected]
        with:
          java-version: '21'
          java-distribution: 'temurin'

      - name: Test with Maven
        run: ./mvnw --batch-mode --no-transfer-progress clean test
Emarie answered 20/12, 2023 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.