clue / reactphp-docker

Async, event-driven access to the Docker Engine API, built on top of ReactPHP.
https://clue.engineering/2019/introducing-reactphp-docker
MIT License
107 stars 16 forks source link

How to access the docker service that hosts the container with my php code? #68

Closed vasily-kartashov closed 3 years ago

vasily-kartashov commented 3 years ago

My web-app runs in a container, and when I try to get the list of other containers running parallel to it, I get the following error message:

"Unable to connect to unix domain socket \"unix:\/\/\/var\/run\/docker.sock\": No such file or directory",
      "message": "Internal server error",

Is this a permission issue or do I need to specify a different URL. Is this possible at all?

clue commented 3 years ago

@vasily-kartashov Thanks for reporting.

I'm not sure I follow what exactly you're trying to do, so perhaps you can share a short gist with the steps to reproduce this locally? It sounds like you're mounting the Docker socket into a container and want to talk to the Docker daemon through this socket from within said container? This should be possible, a short gist to produce would certainly help with diagnosing the problem you're seeing.

vasily-kartashov commented 3 years ago

@clue I have a web-app running inside a docker container named php-fpm, which sits behind another docker container nginx, which runs the webserver.

services:
  php-fpm:
    build: .
    container_name: php-fpm
    ...
  nginx:
    image: nginx
    container_name: nginx
    depends_on:
      - php-fpm
    ...

This web-app has an endpoint /containers that needs to list all containers currently running on the same host. So in my case, I need this method to return something like ['php-fpm', 'nginx', ...]

public function containers() {
    $loop = Factory::create();
    $client = new Client($loop);
    $payload = await(..., $loop);
    return ...
}

What I get back is "Unable to connect to unix domain socket \"unix:\/\/\/var\/run\/docker.sock\": No such file or directory"

vasily-kartashov commented 3 years ago

When using this address

$client = new Client($loop, 'http://host.docker.internal:2375');

I get

Connection to host.docker.internal:2375 failed: 
Last error for IPv4: Connection to tcp://192.168.65.2:2375?hostname=host.docker.internal failed: Connection refused. 
Previous error for IPv6: DNS query for host.docker.internal did not return a valid answer (NOERROR / NODATA)
clue commented 3 years ago

When using Docker, a running container usually does not have access to the Docker socket that is used to control the whole Docker daemon. You can explicitly mount this socket into the container, effectively giving it full control over the whole Docker daemon (listing, starting, stopping and manipulating all other containers/images).

If you're sure that's what you want: In your container configuration you need to use the equivalent of docker run -v /var/run/docker.sock:/var/run/docker.sock …

Unable to connect to unix domain socket "unix:///var/run/docker.sock": No such file or directory`

This error message indicates this files has not been mounted into the container.

Depending on how you run your Docker daemon, you may also be able to access it over TCP/IP sockets, but I would usually recommend the socket path unless you're sure what you're doing. Your other error message seems to indicate that's what you're trying to achieve here?

vasily-kartashov commented 3 years ago

Thank you, @clue!

I was able to get it working on my MacOS host by using this trick https://bryanavery.co.uk/enabling-docker-remote-api-on-osx/ and addressing the host through

$client = new Client($loop, 'http://host.docker.internal:2375');
clue commented 3 years ago

@vasily-kartashov Thanks for reporting back and happy to hear you've got this working now! :+1: