Docker-in-Docker Private Repository “No Basic Auth Credentials”

Docker-in-Docker Private Repository “No Basic Auth Credentials”

Check the Docker client’s credentials

The useful distinction in the original Jenkins example still holds: authenticate in the environment where the Docker client runs. A login in another container or user account does not necessarily give that client access to the credentials.

The filename is config.json, correcting config.cfg in the original post. Docker normally uses ~/.docker/config.json; DOCKER_CONFIG selects a different directory, and docker --config overrides that variable for one command. If the configuration names a credential helper, that helper must also be available to the client.

AWS ECR example

Run login and push from the same client environment. Replace the region, account and repository below with the registry you actually use. The hostname used for login must match the hostname in the image tag.

aws ecr get-login-password --region eu-west-1 |
  docker login --username AWS --password-stdin 111122223333.dkr.ecr.eu-west-1.amazonaws.com

docker push 111122223333.dkr.ecr.eu-west-1.amazonaws.com/YOUR_REPOSITORY:YOUR_TAG

ECR authentication tokens last 12 hours. A successful login does not by itself grant push permission: the AWS identity also needs permission for the target repository.

Checks before changing a pipeline

  • Confirm which user and container execute both Docker commands.
  • Check whether DOCKER_CONFIG or --config points to a different directory.
  • Check the exact registry hostname, AWS region and token age.
  • Keep secrets out of build logs and image layers. Pass the login password through standard input; do not print the configuration file or copy a workstation's entire credential directory into an image.

References: Docker CLI configuration, Docker login and credential helpers, and AWS ECR authentication. The original Jenkins account below describes the specific older pipeline.

Original 2018 post

Recently I was frustrated in a Jenkins build when I was running Docker-in-Docker to build and push a container to AWS Elastic Container Registry (ECR).

The error on push was a familiar `no basic auth credentials` which means some issue with the credentials stored in ~/.docker/config.cfg (or perhaps ~/.dockercfg in earlier versions).

In this case I initially couldn’t understand the error, as the Jenkins declarative pipeline was using a docker.withRegistry function for the registry login, and this was being successfully written to, so what was going on?

Eventually it occurred to me, although it’s not obvious at first – as we’re running docker-in-docker, you might assume that the credentials are looked for relative to where the Docker daemon is running (i.e. on the host), but actually it’s being looked for relative to where the client is calling the daemon from. In this case – within the container. The docker.withRegistry that I was doing with Jenkins was creating credentials on the host – not within the container where the client itself was running.

There were two possible solutions here – one is to ensure you run the docker login command within the client context of the docker-in-docker container, or to mount the .docker directory on the host into the container using something like `-v /root/.docker:/root/.docker` depending on what user you’re running your containers as.