1

I can make cUrl calls to Docker API but if I run the same script from a container (docker-compose), I can't reach any API endpoint.

My requests looks like :

$ curl --unix-socket /var/run/docker.sock -X POST http:/localhost/containers/json

The reason could be the use of localhost but I can't find the solution for now. Any suggestions?

EDIT : Here's a brief summary of the stack i'm using (Api-Platform https://api-platform.com/). Every container is attached to an "api_default" bridge network :

  • php = Symfony based application
  • nginx = NGINX web server
  • psql = Hosts the main database
  • mssql = Used to sync datas
  • ...

I do have a shell script in my "php" container which is meant to reach the Docker API. To summarize, I request the "mssql" container to sync with an external service and then I ask to "psql" container to copy those datas (export/import done with csv files through shared volumes).

The problem is :

  • If I do docker-compose exec php bin/console app:sync (Symfony command which runs the script), everything works fine : the containers communicate through docker.sock with the Docker API and I can sync my databases.
  • But if I run the same script with an api endpoint (localhost:8080/api/sync) or via a VueJS app (Axios), the Docker API never return any response.

Below is a part of my script :

curl -XPOST -H 'Content-Type: application/json' \
      --unix-socket /var/run/docker.sock http:/localhost/containers/mssql/exec \
      -d '{
        "AttachStdout":true,
        "Tty":true,
        "Cmd":["/opt/mssql-tools/bin/sqlcmd", ...]
      }'

And here is the way I call my Symfony command in the api endpoint Controller :

 /**
  * @Route("/api/sync", name="sync", methods={"GET"})
  */
  public function sync(KernelInterface $kernel)
  {
    $application = new Application($kernel);
    $application->setAutoExit(false);

    $input = new ArrayInput(array(
        'command' => 'app:sync'
    ));

    $output = new BufferedOutput();
    $application->run($input, $output);
    $content = $output->fetch();

    return new Response($content);
  }

Maybe should I replace "localhost" with "api_default" to reach the good network, but that doesn't work ... ?

3
  • 1
    Have you mapped the docker socket into the container? Can you provide us with your docker-compose.yml? Commented Feb 21, 2020 at 0:24
  • @RobertSeaman Yes, the docker socket has been mapped like so in every container involved in my calls : volumes: - /var/run/docker.sock:/var/run/docker.sock Commented Feb 21, 2020 at 8:17
  • Check this answer Commented Mar 24, 2021 at 10:04

2 Answers 2

1

the localhost you try to connnect is the localhost in the container you run curl

you should find and replace with its host ip

Sign up to request clarification or add additional context in comments.

Comments

1

Yep. If you want to communicate between one docker container and another docker container, at the very least, you need to use the service name instead of localhost because, as @BMW said, localhost is relative to the machine you are on, and from the container's point of view, localhost is the container itself.

I had a similar situation recently where it wasn't enough to use the service name. I also had to create a network and add each service to that network. Like this:

my_service:
    ...
    ...
    ...
    networks:
      - backend

networks:
  backend:
    driver: bridge

2 Comments

Hi, there's already a bridge network in my stack named "api_default". How could I reach it ? curl http:/api_default/containers/json ? Already tried but no more luck ...
I think that, instead of using the network name in the URI, use the service name. So, my_service/containers/json... If you're struggling to find an answer (like I was a while ago), you can use docker exec -it container_name sh to open a shell on the container. Then you can try and curl from within the container to see what works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.