Home > Back-end >  Connect two containers through docker network
Connect two containers through docker network

Time:03-22

My objective is connect two different containers to get data, in other words:

  • I have an instance of OpenCTI working in my docker , and I can access it through my browser (http://localhost:8080).
  • Consequently, I am developing another one to get data from OpenCTI.

To connect both, I already created a docker network called "minharede".

However is not working.

The configuration of my containers is:

Docker-compose file of OpenCTI:

version: '3'
  services:
    ...
networks: 
  default: 
    external: 
      name: minharede #docker network created for the purpose

volumes:
  esdata:
  s3data:
  redisdata:
  amqpdata:

Docker-Compose file Container B:

version: '3.4'

services:
  teste:
    image: teste
    build:
      context: .
      dockerfile: ./Dockerfile
networks: 
  default: 
    external: 
      name: minharede  #docker network created for the purpose

The config.yml of container B is:

opencti:
  url: "http://localhost:8080"
  token: "xxxxxxxxxxxxxxxxxxxxxxxxxxx" #is hidden to post here

connector:
  id: "245b2de5-b85e-4236-bedd-97540b133ea2"
  type: "INTERNAL_ENRICHMENT"
  name: "osthreatenrichment"
  scope: "IPv4-Addr, IPv6-Addr, Domain-Name"
  auto: true
  confidence_level: 70 #From 0 (unknown) to 100 (Fully trusted)
  log_level: "info"

When I try to run my container B on Visual Code to test it (it's connected to the docker), I get this error:

Exception has occurred: ValueError OpenCTI API is not reachable. Waiting for OpenCTI API to start or check your configuration...

Anyone can helpe me?? Thank you guys!

(image attached) API is not reachable

CodePudding user response:

The compose reference has this example:

services:
  some-service:
    networks:
     - some-network
     - other-network

And it states:

Networks to join, referencing entries under the top-level networks key.

You need to specify the network definition at the top level of your compose file, and in your service definition you need to specify the named network.

However that's not the whole story. As @davidmaze suggests, it will be easier to accomplish this within one compose file rather than multiple. Docker compose treats each compose as a separate "app" and everything within a compose is "namespaced" to that app.


In order to get what you want you'll need to host your named network outside of the compose file. The docker network command is the direction you'd have to go in, but I think a whole tutorial on how to achieve this is outside the scope of an SO answer.

In order to maintain a solution to this, every developer workstation would have to hold and maintain an identically configured named network which both compose-apps could join. This is counterproductive -- the point of developing within a docker compose is to hold the entire development environment within the repository itself.

In any case, the key component is building a named network on your workstation with docker network create <name> and then attaching to it within your compose file via the external attribute.

https://docs.docker.com/compose/networking/#use-a-pre-existing-network (scroll up just a tad, the documentation site for docker misaligns by about 150px when an #anchor is loaded):

If you want your containers to join a pre-existing network, use the external option:

services:
  # ...
networks:
  default:
    external:
      name: my-pre-existing-network

CodePudding user response:

You are using http://localhost:8080 as the target, which cannot work, as each container is its own localhost.

opencti:
  url: "http://localhost:8080" # this should be the other services name

Change it to the target container's network alias (compose service name).


When I replicate your setup, I get a deprecation warning

WARN[0000] network default: network.external.name is deprecated in favor of network.name 

I have fixed this warning, and could successfully create the setup.

First, I create the network:

docker network create minharede

Then, I create a dummy service in a.yaml and run docker compose -p a -f a.yaml up -d:

# a.yaml
services:
  my-svc:
    image: traefik/whoami
networks:
  default:
    name: minharede
    external: true

Finally, I create another service in a different file to curl for the network alias whoami of the service.

# b.yaml
services:
  curl:
    image: curlimages/curl
    command: -s my-svc
networks:
  default:
    name: minharede
    external: true

When, I run docker compose -p b -f b.yaml up I can see the following output.

Attaching to curl_1
curl_1  | Hostname: d63e37dd5363
curl_1  | IP: 127.0.0.1
curl_1  | IP: 172.22.0.2
curl_1  | RemoteAddr: 172.22.0.3:38960
curl_1  | GET / HTTP/1.1
curl_1  | Host: my-svc
curl_1  | User-Agent: curl/7.82.0-DEV
curl_1  | Accept: */*
curl_1  | 
curl_1 exited with code 0

So what you are trying to do is certainly possible. You are just using the wrong hostname. In my example, you can see the service name in the compose file of the service I am trying to curl is my-svc. That's also what I am using for the hostname in the curl command.


You could actually simplify this by not using an external network for a but still reference a's default network as external in b.

# a.yaml
networks:
  default:
    name: minharede
# b.yaml
networks:
  default:
    name: minharede
    external: true

Then you only need to make sure you start a before b.

  • Related