Docker-compose, SSH configuration and Port information retrieval and use

Hi,

Docker-compose does not use the Port information when fetching information from $HOME/.ssh/config.

I have built a Docker host using Vagrant and VirtualBox.
Using vagrant ssh-config I can get a correct SSH configuration item as follow :

(Docker version infos at the end)

Host vdi-00-control-00
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/tmp/.vagrant/machines/vdi-00-control-00/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

Creating the context

docker context create --docker "host=ssh://vagrant@vdi-00-control-00" --default-stack-orchestrator swarm c0 

docker context use c0

running docker-compose ps

PS C:\tmp> docker-compose ps        
Traceback (most recent call last):
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 670, in urlopen
    httplib_response = self._make_request(
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 426, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Python39\lib\http\client.py", line 1347, in getresponse
    self.close()
  File "C:\Python39\lib\http\client.py", line 933, in close
    sock.close()   # close it manually... there may be other refs
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\transport\sshconn.py", line 102, in close
    self.proc.stdin.flush()
OSError: [Errno 22] Invalid argument

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python39\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 726, in urlopen
    retries = retries.increment(
  File "C:\Python39\lib\site-packages\urllib3\util\retry.py", line 410, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Python39\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 670, in urlopen
    httplib_response = self._make_request(
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 426, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "C:\Python39\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    httplib_response = conn.getresponse()
  File "C:\Python39\lib\http\client.py", line 1347, in getresponse
    self.close()
  File "C:\Python39\lib\http\client.py", line 933, in close
    sock.close()   # close it manually... there may be other refs
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\transport\sshconn.py", line 102, in close
    self.proc.stdin.flush()
urllib3.exceptions.ProtocolError: ('Connection aborted.', OSError(22, 'Invalid argument'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\api\client.py", line 215, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\api\daemon.py", line 183, in version
    return self._result(self._get(url), json=True)
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\utils\decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\api\client.py", line 238, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "C:\Python39\lib\site-packages\requests\sessions.py", line 543, in get
    return self.request('GET', url, **kwargs)
  File "C:\Python39\lib\site-packages\requests\sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python39\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python39\lib\site-packages\requests\adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', OSError(22, 'Invalid argument'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python39\Scripts\docker-compose-script.py", line 33, in <module>
    sys.exit(load_entry_point('docker-compose', 'console_scripts', 'docker-compose')())
  File "c:\code\docker_compose_i1\compose\cli\main.py", line 81, in main
    command_func()
  File "c:\code\docker_compose_i1\compose\cli\main.py", line 198, in perform_command
    project = project_from_options('.', options)
  File "c:\code\docker_compose_i1\compose\cli\command.py", line 60, in project_from_options
    return get_project(
  File "c:\code\docker_compose_i1\compose\cli\command.py", line 152, in get_project
    client = get_client(
  File "c:\code\docker_compose_i1\compose\cli\docker_client.py", line 41, in get_client
    client = docker_client(
  File "c:\code\docker_compose_i1\compose\cli\docker_client.py", line 170, in docker_client
    client = APIClient(use_ssh_client=not use_paramiko_ssh, **kwargs)
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\api\client.py", line 198, in __init__
    self._version = self._retrieve_server_version()
  File "C:\Python39\lib\site-packages\docker-4.4.4-py3.9.egg\docker\api\client.py", line 222, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', OSError(22, 'Invalid argument'))

Chaning the context by adding the port information

docker context update --docker "host=ssh://vagrant@vdi-00-control-00:2222" --default-stack-orchestrator swarm c0

then docker-compose ps

Name   Command   State   Ports
------------------------------
Exception ignored in: <function Popen.__del__ at 0x0000023EF2165DC0>
Traceback (most recent call last):
  File "C:\Python39\lib\subprocess.py", line 1055, in __del__
    self._internal_poll(_deadstate=_maxsize)
  File "C:\Python39\lib\subprocess.py", line 1457, in _internal_poll
    if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
OSError: [WinError 6] Descripteur non valide
PS C:\tmp> docker-compose version
docker-compose version 1.29.0dev, build unknown
docker-py version: 4.4.4
CPython version: 3.9.4
OpenSSL version: OpenSSL 1.1.1i  8 Dec 2020

PS C:\\tmp> docker version
Client:
 Version:           19.03.12
 API version:       1.40
 Go version:        go1.13.12
 Git commit:        0ed913b8-
 Built:             07/28/2020 16:36:03
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       363e9a8
  Built:            Tue Mar  2 20:15:47 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0