I'm trying to connect a Thrift client (client) to a Thrift server (server) on the same host; the server and client must be in separate docker containers.
I'm using the python implementation of Apache Thrift, Thriftpy v0.3.9. The host is Ubuntu 16.04, Docker is version 18.06.0-ce, and docker-compose is version 1.17.0. I'm using a python:3.6.6-alpine3.8 image.
I can successfully connect the client to the server on the same host so long as they're not containerized. However, I need them in containers.
My docker-compose.yml:
version: "3"
services:
thrift_client:
build: .
ports:
- "6002:6000"
links:
- thrift_server
thrift_server:
image: thrift_server
ports:
- "6001:6000"
The server runs successfully. However, the client makes the following exception:
"Could not connect to %s" % str(addr)) thriftpy.transport.TTransportException: TTransportException(type=1, message="Could not connect to ('thrift_server', 6000)")
I'm following this little demo linked below with only slight deviations so as to do it with docker. https://thriftpy.readthedocs.io/en/latest/
My pinpong.thrift file:
service PingPong {
string ping(),
}
thrift_server.py:
import thriftpy
pingpong_thrift = thriftpy.load("pingpong.thrift", module_name="pingpong_thrift")
from thriftpy.rpc import make_server
class Dispatcher(object):
def ping(self):
return "pong"
server = make_server(pingpong_thrift.PingPong, Dispatcher(), 'localhost', 6000)
server.serve()
thrift_client.py:
import thriftpy
pingpong_thrift = thriftpy.load("pingpong.thrift", module_name="pingpong_thrift")
from thriftpy.rpc import make_client
client = make_client(pingpong_thrift.PingPong, 'thrift_server', 6000)
client.ping()
Again, this works fine without using Docker on the host. Of course, I use 'localhost' in lieu of 'thrift_server' for the client when doing it without Docker.
The goal is to experiment making calls from the thrift client to the thrift server on the same host. Therefore, docker-compose is not necessary for this simple learning example.
First of all, the ports used in the above question are all wrong. Both the thrift client and thrift server must listen to the same port on the host.
Therefore, I replaced this line for the thrift client
client = make_client(pingpong_thrift.PingPong, 'thrift_server', 6000)
to the following:
client = make_client(pingpong_thrift.PingPong, 'localhost', 6000)
Docker bridge doesn't allow 2 or more containers to listen to the same port. Therefore, I use the host network. To my understanding you can connect to the host network on docker for Linux (not sure about Windows) but not Mac.
In any case, I simply did the following:
$ docker run -it --network=host --name thrift_server_container -p=0.0.0.0:6000:6000 thrift_server python thrift_server.py
Then in another terminal:
$ docker run -it --network=host --name thrift_client_container -p=0.0.0.0:6000:6000 thrift_client python
The second command will put you in the python repl of the client. You can then start an instance of the thrift client in the repl and ping the thrift server. Of course you could run thrift_client.py in the second command instead, but I found it easier to experiment with thrift in the repl.