Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

making docker containers communicate through port

Im trying to create 2 docker containers and run them in a way they can communicate with each other through a port in localhost. I have created 2 python files as sender and receiver. When Im running them without docker they communicate nicely. But with docker they are not running properly.

Sender

Python script

#!/usr/bin/python
# -*- encoding: utf-8 -*-
import socket
import time
import sys

print sys.argv[1]
print sys.argv[2]


for i in range(1,10):
    time.sleep(2)
    data = "My parameters that I want to share with the server on ith iteration %d" % (i)
    print "sedning data: %d" % (i)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((sys.argv[1], int(sys.argv[2])))
    sock.sendall(data)
    sock.close()

Dockerfile

FROM ubuntu

RUN \
  apt-get update && \
  apt-get install -y python python-dev python-pip python-virtualenv && \
  rm -rf /var/lib/apt/lists/*

ADD script.py /root/script.py

CMD python -u /root/script.py $SEND_HOST $SEND_PORT

Receiver

Python script

#!/usr/bin/python
# -*- encoding: utf-8 -*-
import socket
import sys



print sys.argv[1]
print sys.argv[2]

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((sys.argv[1], int(sys.argv[2])))
s.listen(3)

while True:
    conn, addr = s.accept()
    data = conn.recv(1024)
    conn.close()
    print "received data from sender: %s" % (data)

Dockerfile

FROM ubuntu

RUN \
  apt-get update && \
  apt-get install -y python python-dev python-pip python-virtualenv && \
  rm -rf /var/lib/apt/lists/*

ADD script.py /root/script.py

CMD python -u /root/script.py $LISTEN_HOST $LISTEN_PORT

Run command for Receiver

docker run --name="testListen" -p 5555:5555 --env LISTEN_HOST="localhost" --env LISTEN_PORT="5555" docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1

Run command for Sender

docker run --name="testTalk" --env SEND_HOST="localhost" --env SEND_PORT="5555" docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1

Before running the containers I made sure that both images are built. Can anyone tell why its not running properly?

Here is the simple python running command that works just fine without docker:

on receiver python script.py localhost 5555

on sender python script.py localhost 5555

like image 389
Ayon Nahiyan Avatar asked Mar 09 '23 18:03

Ayon Nahiyan


1 Answers

I think you have 3 options here to get this working:

  1. Create a docker network to connect the hosts:

    docker network create --driver bridge sample-sendr-rcv-test
    docker run  --name="testListen" --env LISTEN_HOST="0.0.0.0" --env LISTEN_PORT="5555" --network=sample-sendr-rcv-test -d docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
    docker run --name="testTalk" --env SEND_HOST="testListen" --env SEND_PORT="5555" --network=sample-sendr-rcv-test -d docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
    
  2. Use docker-compose with a docker-compose.yml like:

    version: '2'
    services:
      sender:
        image: docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
        # build: sender
        environment:
          SEND_HOST: receiver
          SEND_PORT: 5555
      receiver:
        image: docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
        # build: receiver
        environment:
          LISTEN_HOST: '0.0.0.0'
          LISTEN_PORT: 5555
    
  3. Use host networking:

    docker run  --name="testListen" --env LISTEN_HOST="127.0.0.1" --env LISTEN_PORT="5555" --net=host -d docker.io/ayonnayihan/sample-sendr-rcv-test:receiver0.1
    docker run --name="testTalk" --env SEND_HOST="localhost" --env SEND_PORT="5555" --net=host -d docker.io/ayonnayihan/sample-sendr-rcv-test:sender0.1
    

The third option is the most similar to what you are currently doing but I would not recommend it for reasons explained below. Either of the other options will work but may not be worth learning docker-compose if you are just starting with docker.

The reason you are having an issue is that the containers each have their own idea of 'localhost' because they are in a different network namespace. This means that 'localhost' on your 'testTalk' container does not resolve to the host where your listener is running. When you use --net=host (option 3 above) you are removing the separate namespace for the containers, thus removing some of the security benefits of using docker.

like image 174
joelnb Avatar answered Mar 16 '23 09:03

joelnb