cli icon indicating copy to clipboard operation
cli copied to clipboard

`docker context use` fails silently when `DOCKER_HOST` is set

Open bzhb opened this issue 3 years ago • 4 comments

Description

docker context use ecs-context fails silently to change context when the environment variable DOCKER_HOST is set.

For the same reason commands with --context will also fail with little indication of the reason, like :

docker --context ecs-context compose -f docker-compose.ecs.yaml convert
docker --context ecs-context compose -f docker-compose.ecs.yaml up -d

Reproduce

  1. Set the variable in the environment :
$ export DOCKER_HOST=unix:///var/run/docker.sock
$ echo $DOCKER_HOST
unix:///var/run/docker.sock
  1. Try to switch context everything looks fine, including a 0 return code, except that the context is not changed :
$ docker context use ecs-context
ecs-context
$ echo $?
0
$ docker context show
default
$ docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
ecs-context         ecs                 credentials read from environment 

Expected behavior

When DOCKER_HOST is not set we can switch context :

$ docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
ecs-context         ecs                 credentials read from environment                                                             
$ docker context show
default
$ unset DOCKER_HOST
$ echo $DOCKER_HOST

$ docker context use ecs-context
ecs-context
$ docker context show
ecs-context
$ docker context use default
default
$ docker context show
default

docker version

Client: Docker Engine - Community
 Cloud integration: v1.0.29
 Version:           20.10.2
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        2291f61
 Built:             Mon Dec 28 16:11:26 2020
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.13
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.15
  Git commit:       906f57f
  Built:            Thu Mar 31 19:21:13 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.13
  GitCommit:        9cc61520f4cd876b86e77edfeb88fbcd536d1f9d
 runc:
  Version:          1.1.3
  GitCommit:        1e7bb5b773162b57333d57f612fd72e3f8612d94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

docker info

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  compose: Docker Compose (Docker Inc., v2.10.0)

Server:
 Containers: 5
  Running: 3
  Paused: 0
  Stopped: 2
 Images: 37
 Server Version: 20.10.13
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 9cc61520f4cd876b86e77edfeb88fbcd536d1f9d
 runc version: 1e7bb5b773162b57333d57f612fd72e3f8612d94
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.14.287-215.504.amzn2.x86_64
 Operating System: Amazon Linux 2
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 1.944GiB
 Name: ip-1-1-136-219.eu-west-3.compute.internal
 ID: 6VAI:6ATQ:YQHA:EJ6H:JBXC:CFZ5:T4LU:PHOV:T4EJ:7LVI:6NZM:LPBO
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Additional Info

The bug was especially stealthy for me as we I was logged on the machine the variable was not set, but when running it with gitlab-runner, it had that variable set in its environment.

May be related to the fix for #3667 (https://github.com/docker/cli/pull/3668https://github.com/docker/cli/pull/3668)

$ docker compose version
Docker Compose version v2.10.0

bzhb avatar Aug 31 '22 16:08 bzhb

maybe try upgrading the docker cli? i usually see this warning - https://github.com/docker/cli/blob/master/cli/command/context/use.go#L52

nicks avatar Aug 31 '22 20:08 nicks

I still have the same behavior on my local machine with docker 20.10.17 :

$ sudo -E docker context show
default
$ sudo -E docker context list
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
ecs-context         ecs                 credentials read from environment                                                                                                                                
$ sudo -E env | grep DOCKER
DOCKER_HOST=unix:///var/run/docker.sock
$ sudo -E docker context use ecs-context
ecs-context
$ sudo -E echo $?
0
$ sudo -E docker context show
default
$ unset DOCKER_HOST
$ sudo -E env | grep DOCKER
$ sudo -E docker version
Client:
 Cloud integration: v1.0.29
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.18.3
 Git commit:        100c70180f
 Built:             Sat Jun 11 23:27:28 2022
 OS/Arch:           linux/amd64
 Context:           ecs-context
 Experimental:      true

Server:
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.3
  Git commit:       a89b84221c
  Built:            Sat Jun 11 23:27:14 2022
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6.m
 runc:
  Version:          1.1.4
  GitCommit:        
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ docker context show
ecs-context
$ sudo -E docker context show
ecs-context
$ sudo -E docker version
Client:
 Cloud integration: v1.0.29
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.18.3
 Git commit:        100c70180f
 Built:             Sat Jun 11 23:27:28 2022
 OS/Arch:           linux/amd64
 Context:           ecs-context
 Experimental:      true

Server:
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.3
  Git commit:       a89b84221c
  Built:            Sat Jun 11 23:27:14 2022
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6.m
 runc:
  Version:          1.1.4
  GitCommit:        
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Also unsetting the environment variable dynamically change the context :

$ sudo -E docker context show
ecs-context
$ export DOCKER_HOST=unix:///var/run/docker.sock
$ sudo -E docker context show
default
$ unset DOCKER_HOST
$ sudo -E docker context show
ecs-context

And the value of the variable does not matter :

$ export DOCKER_HOST=bla
$ sudo -E docker context show
default
$ unset DOCKER_HOST
$ sudo -E docker context show
ecs-context
$ export DOCKER_HOST=""
$ sudo -E docker context show
default

No warning for me, even if the mentioned warning already existed in v20.10.2 (with a different condition) : https://github.com/docker/cli/blob/v20.10.2/cli/command/context/use.go#L44

What controls where dockerCli.Err messages are displayed ? I have try with --debug and -l "debug" flags with no more output

bzhb avatar Aug 31 '22 23:08 bzhb

I think what is going on when the variable is set is :

  • docker context use ecs-context do succeed to switch context, so the warning is not displayed as it is written to the error output.
  • But right after the context change, when the next docker command is run it sees the environment variable set, so it SILENTLY switch back to the default context.

For commands like docker --context ecs-context compose -f docker-compose.ecs.yaml up -d, I imagine it is dealt with internally as two successive commands, like docker context use ecs-context ; docker compose -f docker-compose.ecs.yaml up -d, which would explain it behave the same way.

From my perspective the fact that an environment variable has precedence on command-line argument is wrong. If for some reason it is not possible to change this behavior, at the very least a warning should be displayed in the dockerCli.Out() every time the environment variable take precedence and switch context (so not in the docker context use command)

bzhb avatar Sep 06 '22 09:09 bzhb

i think you're getting sent down https://github.com/docker/compose-cli/blob/main/cli/cmd/context/use.go#L17, compose-cli's fork of the context commands.It doesn't have the nice warnings that docker/cli does. let me go complain to them about how to reconcile it.

nicks avatar Sep 14 '22 18:09 nicks