Answer a question

Description of the situation : I have a Ubuntu VM running on remote computer B. I can access this computer B via SSH executed on my host (computer A). When I enter an interactive shell via SSH on computer B, I can execute all my docker commands without any trouble, the steps are the following :

  • ssh user@remote_IP (enters interactively in the remote shell)
  • docker-compose run -d --name wfirst --user 1000:1000 container (compose a docker container and starts it)

This works perfectly, my container is mounted, up and running. However, if I try to run that command in a non-interactive way by writing in my host terminal :

  • ssh user@remoteIP "cd /path_to_docker_file;docker-compose run -d --name wfirst --user 1000:1000 container"

The command does not succeed, my container is not mounted and does not run. I was able to get more information by using the "--verbose" flag on the docker-compose command.

Here the interesting part of the output of the successful method :

    compose.config.config.find: Using configuration files: ./docker-compose.yml
    WARNING: compose.config.environment.__getitem__: The DISPLAY variable is not set. Defaulting to a blank string.
    WARNING: compose.config.environment.__getitem__: The NO_PROXY variable is not set. Defaulting to a blank string.
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    urllib3.connectionpool._new_conn: Starting new HTTP connection (1): localhost:2375
    urllib3.connectionpool._make_request: http://localhost:2375 "GET /v1.25/version HTTP/1.1" 200 758
    compose.cli.command.get_client: docker-compose version 1.21.0, build unknown
    docker-py version: 3.4.1
    CPython version: 3.7.5
    OpenSSL version: OpenSSL 1.1.1c  28 May 2019
    compose.cli.command.get_client: Docker base_url: http://localhost:2375
    ...

We can see that a HTTP connection to docker is successfully established. The command then continues its execution and is able to create the container from the docker image.

Here the output of the failing method :

    compose.config.config.find: Using configuration files: ./docker-compose.yml
    compose.config.environment.__getitem__: The DISPLAY variable is not set. Defaulting to a blank string.
    compose.config.environment.__getitem__: The NO_PROXY variable is not set. Defaulting to a blank string.
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 384, in _make_request
        six.raise_from(e, None)
      File "<string>", line 3, in raise_from
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
        httplib_response = conn.getresponse()
      File "/usr/lib/python3.7/http/client.py", line 1344, in getresponse
        response.begin()
      File "/usr/lib/python3.7/http/client.py", line 306, in begin
        version, status, reason = self._read_status()
      File "/usr/lib/python3.7/http/client.py", line 267, in _read_status
        line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
      File "/usr/lib/python3.7/socket.py", line 589, in readinto
        return self._sock.recv_into(b)
    socket.timeout: timed out

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
        timeout=timeout
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
        _stacktrace=sys.exc_info()[2])
      File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 367, in increment
        raise six.reraise(type(error), error, _stacktrace)
      File "/usr/lib/python3/dist-packages/six.py", line 693, in reraise
        raise value
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
        chunked=chunked)
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 386, in _make_request
        self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 306, in _raise_timeout
        raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
    urllib3.exceptions.ReadTimeoutError: UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/bin/docker-compose", line 11, in <module>
        load_entry_point('docker-compose==1.21.0', 'console_scripts', 'docker-compose')()
      File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 71, in main
        command()
      File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 124, in perform_command
        project = project_from_options('.', options)
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 41, in project_from_options
        compatibility=options.get('--compatibility'),
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 121, in get_project
        host=host, environment=environment
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 95, in get_client
        version_info = six.iteritems(client.version())
      File "/usr/lib/python3/dist-packages/docker/api/daemon.py", line 181, in version
        return self._result(self._get(url), json=True)
      File "/usr/lib/python3/dist-packages/docker/utils/decorators.py", line 46, in inner
        return f(self, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/docker/api/client.py", line 198, in _get
        return self.get(url, **self._set_request_timeout(kwargs))
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 546, in get
        return self.request('GET', url, **kwargs)
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
        r = adapter.send(request, **kwargs)
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 529, in send
        raise ReadTimeout(e, request=request)
    requests.exceptions.ReadTimeout: UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

We can see that the HTTP connection cannot be established.

Why do I need to send my commands in a non-interactive way ? Originally, I want to send those commands using Jenkins (I added a SSH plugin in Jenkins), and I noticed that the docker commands were not working (same output as shown in this post). After a couple of tests, I realised that when Jenkins uses SSH, he sends the commands in a non-interactive way : - ssh user@remote_IP "commands_to_execute"

This non-interactive way is not an issue for simple commands, but it appears to be an issue for some docker commands which require to be executed in an interactive shell I guess ? Has someone found a work-around to successfully execute docker commands in a non-interactive shell ? Any help, hint, or alternative solutions will be greatly appreciated, as I tried a lot of things without any success so far..

Answers

Did you check if it is docker-engine running on tcp or by unix socket?

Maybe isn't reading right environment vars when you login by ssh u @ h "command".

If it's running on unix socket (by default) try...

ssh user @ remoteIP "cd /path_to_docker_file;DOCKER_HOST=unix:///var/run/docker.sock docker-compose run -d --name wfirst --user 1000: 1000 container"

or if is running on TCP, you can try ...

ssh user @ remoteIP "cd /path_to_docker_file;DOCKER_HOST=tcp://127.0.0.1:2375 docker-compose run -d --name wfirst --user 1000: 1000 container"

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐