Watchtower: Mounting docker config not working as expected

Created on 22 Jul 2017  路  12Comments  路  Source: containrrr/watchtower

Testing watchtower and passing REPO_USER and REPO_PASS as environment variables in the docker run command line works successfully.

Trying to switch to using -v /Users/(user)/.docker/config.json:/config.json instead of passing environment variables is not working and instead I get:

DEBU[0049] No credentials for (organization) in /config.json 
DEBU[0049] No authentication credentials found for (organization)/(repository):(tag) 

I tried regenerating the /Users/(user)/.docker/config.json using docker login but no change in results.

I am able to pull the image just fine on the host using docker pull so the credentials for docker on the host are valid.

My watchtower docker image is v2tec/watchtower
My docker version is 17.06.0-ce, build 02c1d87 on Mac.
My command line is docker run -v /var/run/docker.sock:/var/run/docker.sock -v /Users/(user)/.docker/config.json:/config.json v2tec/watchtower --interval 15 --debug

I also just tried this on our Ubuntu server (also 17.06.0-ce, build 02c1d87) to see if the problem was tied to Mac, I get the same results.

Is there any further way to debug this?

Abandoned

Most helpful comment

It has already been answered by phiberoptick. This is neither a bug nor does it need a workaround, this is the expected behavior of docker: https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior

If you use -v or --volume to bind-mount a file or directory that does not yet exist on the Docker host, -v creates the endpoint for you. It is always created as a directory.

If you use --mount to bind-mount a file or directory that does not yet exist on the Docker host, Docker does not automatically create it for you, but generates an error.

Creating the config.json on the host like this echo {} > ~/.docker/config is enough for watchtower to work on all my hosts.

All 12 comments

Have you tried the workaround mentiond in #68 ? Appending the registry should work. Unfortunatelay this is still bug, which should get fixed in the next patch release.

@stffabi I think you referenced the wrong issue #, as there is nothing in #68

Hmm strange, I see content... Maybe a problem of github.

Try changing the image name of your private containers to e.g. index.docker.io/adventhp/cavo:docker

Oh, sometimes when I refresh the 68 issue I also don't see any content. Refreshing the page again in the browser, and content shows up. Seems to me that github is having some issues...

If I refresh the page after going to the link, the content shows up. Strange indeed. I will try the workaround later when I am in a position to test.

Are there any new on this ticket? I experience the same issue with google cloud platform.

When i run watchtower from console it works fine:

docker run \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e REPO_USER="_json_key" \
  -e REPO_PASS="$(cat key.json)" \
  v2tec/watchtower --label-enable --debug --interval 60 

But its not working if i use the credentials from docker in docker-compose:

    image: v2tec/watchtower
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /Users/myusername/.docker/config.json:/config.json
    command: --label-enable --debug --interval 5
    restart: unless-stopped

I'm also able to pull the image with docker pull like @patakijv but when i try it with the docker-compose file it then it says im not authorised.

I have been running into this as well. I'm not quite sure if it is the same cause. The errors are identical and all point to not being able to read the config.json.

After a little reading, it appears that if the file does not exist in the image, when starting the container the -v switch will create it but ALWAYS as a directory.

See "https://docs.docker.com/storage/bind-mounts/#choosing-the--v-or---mount-flag"

This can be seen in the logs as well if you use the debug flag:

time="2018-07-08T08:46:07Z" level=error msg="Unable to find default config file /config.json - read /config.json: is a directory" 
 time="2018-07-08T08:46:07Z" level=info msg="Unable to update container /portainer, err='/config.json - read /config.json: is a directory'. Proceeding to next." 
 time="2018-07-08T08:51:07Z" level=error msg="Unable to find default config file /config.json - read /config.json: is a directory" 
 time="2018-07-08T08:51:07Z" level=info msg="Unable to update container /portainer, err='/config.json - read /config.json: is a directory'. Proceeding to next." 
 time="2018-07-08T08:56:07Z" level=error msg="Unable to find default config file /config.json - read /config.json: is a directory" 
 time="2018-07-08T08:56:07Z" level=info msg="Unable to update container /portainer, err='/config.json - read /config.json: is a directory'. Proceeding to next." 

Basically:

Differences between -v and --mount behavior
Because the -v and --volume flags have been a part of Docker for a long time, their behavior cannot be changed. This means that there is one behavior that is different between -v and --mount.

If you use -v or --volume to bind-mount a file or directory that does not yet exist on the Docker host, -v creates the endpoint for you. It is always created as a directory.

If you use --mount to bind-mount a file or directory that does not yet exist on the Docker host, Docker does not automatically create it for you, but generates an error.

I confirmed this by removing removing the directory that was created during the docker run and copying over that file it was supposed to get the bind from.

Restarted watchtower and jackpot!

 time="2018-07-08T09:01:11Z" level=info msg="Waiting for running update to be finished..." 
 time="2018-07-08T09:01:11Z" level=info msg="Found new portainer/portainer:latest image (sha256:7afb7abcfe5f2c54e9a34ddf70337aa7d207eee2bc172100dc439e97bfebfcee)" 
 time="2018-07-08T09:01:11Z" level=info msg="Stopping /portainer (7b1c151727728aaf332caae9ef8a8a8c648b9905fa94b6eb8d1cc6af4a95f3a0) with SIGTERM" 
 time="2018-07-08T09:01:12Z" level=info msg="Creating /portainer" 
 time="2018-07-08T09:01:13Z" level=info msg="Removing image sha256:50c62d83c09c4b49174cb5f52fa099f9cdc2292ccc94e52f5430f2f70b8705a0" 
 time="2018-07-08T09:02:36Z" level=info msg="First run: 2018-07-08 09:07:36 +0000 UTC"

-Ronan

anyone have any luck with this issue? I am having the same problem. Appending the registry still doesnt work for me and trying all the workarounds also is not working for me, anyone have any advice?

Same issue here, I tried everything..

@Garcia1022 @stepri

Ok, I found a workaround. And it's werid as hell! Basically, you need a valid config.json file before you fire up your container. And you probably don't want to use /root/.docker, instead you want to use /home/XXX/.docker where XXX=your_username. In my examples below, I've taken care of this. But neither of these are going to work unless you have a valid /home/XXX/.docker/config.json file. So how do you get one? I'm sure there are better ways of doing it, but this article showed me one way. And it worked. So first go over to Docker Hub. If you don't have an account, create one. Otherwise login to make sure you have the correct username and password. Then what I did was the following:

  1. tear down all containers. Since I use docker-compose, I did the following:
    > $ docker-compose -f /home/XXX/docker/docker-compose.yml down
  2. Log out of Docker Hub
    > $ docker logout
  3. Log in to Docker Hub
    > $ docker login -u -p
  4. Check that /home/XXX/.docker/config.json is populated
    > $ cat /home/XXX/.docker/config.json
{
        "auths": {
                "https://index.docker.io/v1/": {
                        "auth": "FFFAAABBBCCCDDDAAA="
                }
        },
        "HttpHeaders": {
                "User-Agent": "Docker-Client/18.09.1 (linux)"
        }
}
xxx@docker:~$

Now that you have a valid config.json file, use either of the docker run or docker-compose commands:

docker run

docker run -d \
  --name watchtower \
  -v /home/XXX/.docker/config.json:/config.json \
  -v /var/run/docker.sock:/var/run/docker.sock \
  v2tec/watchtower --debug

docker-compose

  watchtower:
    image: v2tec/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/XXX/.docker/config.json:/config.json  
    command: --interval 300
    restart: unless-stopped

You should be ready to go

It has already been answered by phiberoptick. This is neither a bug nor does it need a workaround, this is the expected behavior of docker: https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior

If you use -v or --volume to bind-mount a file or directory that does not yet exist on the Docker host, -v creates the endpoint for you. It is always created as a directory.

If you use --mount to bind-mount a file or directory that does not yet exist on the Docker host, Docker does not automatically create it for you, but generates an error.

Creating the config.json on the host like this echo {} > ~/.docker/config is enough for watchtower to work on all my hosts.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MakerTim picture MakerTim  路  6Comments

simskij picture simskij  路  5Comments

Ezwen picture Ezwen  路  6Comments

alexhaller picture alexhaller  路  3Comments

darox picture darox  路  5Comments