Connection between Docker Containers using SocketIO can't be established

I have the following problem, which feels like it should work, but somehow doesn’t. I have tried a number of solutions posted on the net, but none of them seem to work for my case, and I don’t know what I’m doing wrong.

I have a system of three containers that I am trying to link together using docker-compose: A mongoDB container, and two java-based server containers running on the amazoncorretto base image, which I am going to call alpha and beta. Run locally on my machine, this works nicely. Alpha connects to Mongo via port 27017, and exposes a socket to port 4000, to which Beta successfully connects.

However, when trying to get this to work in docker, the connection from Beta to Alpha fails, even though Alpha has port 4000 exposed. Here’s the files:

Alpha dockerfile:

FROM amazoncorretto:11
COPY image_files /image_files
WORKDIR /image_files
EXPOSE 4000
EXPOSE 52235 
CMD ["java", "-jar", "alpha.jar"]

Beta dockerfile:

FROM amazoncorretto:11
COPY image_files /image_files
WORKDIR /image_files
CMD ["java", "-jar", "beta.jar"]

docker-compose.yml:

version: "3"
services:
    mongodb:
        image: mongo:4.0.4
        container_name: "company-alpha-database"
        environment:
            - MONGO_INITDB_DATABASE=test_database
            - MONGO_INITDB_ROOT_USERNAME=company
            - MONGO_INITDB_ROOT_PASSWORD=pizzaismagic
        volumes:
            - mongo_database_volume:/data/db
        ports:
            - "27017-27019:27017-27019"

    alpha:
        image: company-alpha
        container_name: "company-alpha-container"
        ports:
            - "4000:4000"
            - "52235:52235"
        depends_on:
            - mongodb

    beta:
        image: company-beta
        container_name: "company-beta-container"
        depends_on:
            - alpha

volumes:
    mongo_database_volume:

As for the connection string that Beta uses to connect to Alpha, when run locally, this works with the following connection string:

  • http://localhost:4000

I am aware that in the docker context this needs to be different, and I theoretically know how to implement this. For example, I got Alpha to successfully connect to Mongo using this connection string:

  • mongodb://login:password@mongodb:27017/

Following this logic, I would assume the correct connection string for Beta to Alpha in the docker context to be:

  • http://alpha:4000

However, that does not work. When running docker-compose up , I get the following output:

company-alpha-container | 2020-05-13 06:47:21 [SocketIOServer:128] [INFO]  Session store / pubsub factory used: MemoryStoreFactory (local session store only)
company-alpha-container | 2020-05-13 06:47:21 [A:?] [DEBUG]  Server started on port: 4000
company-alpha-container | 2020-05-13 06:47:21 [SocketIOServer:153] [INFO]  SocketIO server started at port: 4000
company-beta-container | 2020-05-13 06:47:21 [G:?] [DEBUG]  Trying to reconnect to: http://alpha:4000/
company-beta-container | 2020-05-13 06:47:21 [G:?] [DEBUG]  Will try to reconnect again in 1000ms
company-beta-container | 2020-05-13 06:47:22 [G:?] [DEBUG]  Trying to reconnect to: http://alpha:4000/
company-beta-container | 2020-05-13 06:47:22 [G:?] [DEBUG]  Will try to reconnect again in 1000ms

I have also tried the following alternate connection strings, none of which worked:

  • http://host.docker.internal:4000
  • alpha:4000
  • http://localhost:4000
  • http://alpha:4000/
  • http://company-alpha-container:4000/

I have also tried defining a custom network and putting all my services into it, as such:

[...]
    alpha:
        image: company-alpha
        container_name: "company-alpha-container"
        ports:
            - "4000:4000"
            - "52235:52235"
        depends_on:
            - mongodb
        networks:
            - project-net

    beta:
        image: company-beta
        container_name: "company-beta-container"
        depends_on:
            - alpha
        networks:
            - project-net

[...]

networks:
    project-net:
        driver: "bridge"

…but that didn’t work either.

I have also tried giving Beta a link to Alpha, knowing fully well that links are deprecated, but that didn’t work either.

Frankly, at this point I am out of ideas. Based on everything I know of docker and every answer I have found on the net, this should work… but obviously it doesn’t.

Any ideas on how I might resolve this or why this is not working would be greatly appreciated.

After a lot of back and forth, I was able to identify the cause of this behaviour.

The problem was not at all related to the docker configuration (or rather, it was not resolvable by docker configuration). Instead, the hostname of the SocketIO server was localhost, which worked outside of docker, but not within. As soon as I changed it to 0.0.0.0, Beta was able to connect with Alpha just fine both inside and outside of docker.

Here’s what I changed to the part of Alpha that invokes the IOServer:

	private static final String ALPHA_HOSTNAME = "0.0.0.0";

[...]

	Configuration config = new Configuration();
        config.setHostname(ALPHA_HOSTNAME );
        [...]
        server = new SocketIOServer(config);

With that, it works fine with the docker-compose.yml and dockerfiles that I posted at the very beginning.

I hope this solution will help other people who struggle with the same issue.

1 Like