Running matches with docker compose

Hi team,

Thanks for what looks to be another awesome challenge this year!

I’m trying to run the engine and some bots using docker-compose as per the README in the ec-compose folder of the repo.
I think I’m nearly there, I’m just stuck on the 3rd and final step, “profit” :wink:

I’ve added some bot configs to the docker-compose.yml as follows:

version: "3.9"
services:
  runner:
    build: ../game-runner/
    networks:
      - network   
    environment:
      BOT_COUNT: 2          # << changed this
    ports:
      - "5000:5000"
  engine:
    build: ../game-engine
    networks:
      - network 
    environment:
      RunnerIp: runner
      LOG_LEVEL: info
      BOT_COUNT: 2
    depends_on:
      - "runner"
      - "logger"
  logger:
    build: ../game-logger
    networks:
      - network
    environment:
      RUNNER_IPV4: runner
      MATCH_STATUS_FILE: matchState.log
      GAME_COMPLETE_FILE: gameComplete.log
    depends_on:
      - "runner"

  bot1:                               # << added this
    build: 
      context: ../../submission_repo
      args:
        DOCKER_BUILD: "true"
    networks:
      - network
    environment:
      RUNNER_IPV4: runner
    depends_on:
      - "runner"
      - "engine"
      - "logger"

  bot2:                       # << added this
    build: ../starter-bots/PythonBot
    networks:
      - network
    environment:
      RUNNER_IPV4: runner
    depends_on:
      - "runner"
      - "engine"
      - "logger"

The docker images seem to build fine for both the cpp and the python bot, but they have problems actually starting up.

Doing a docker-compose -p "ec" up --build in the directory after making these changes results in:

...
bot1_1    | Error while sending data: connection was stopped before invocation result was received
...
bot2_1    | runner:5000/runnerhub
bot2_1    | Traceback (most recent call last):
bot2_1    |   File "/app/StarterBot.py", line 89, in <module>
bot2_1    |     run_bot()
bot2_1    |   File "/app/StarterBot.py", line 63, in run_bot
bot2_1    |     hub_connection.start()
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/signalrcore/hub/base_hub_connection.py", line 44, in start
bot2_1    |     return self.transport.start()
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/signalrcore/transport/websockets/websocket_transport.py", line 62, in start
bot2_1    |     self.negotiate()
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/signalrcore/transport/websockets/websocket_transport.py", line 93, in negotiate
bot2_1    |     response = requests.post(
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 119, in post
bot2_1    |     return request('post', url, data=data, json=json, **kwargs)
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
bot2_1    |     return session.request(method=method, url=url, **kwargs)
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
bot2_1    |     resp = self.send(prep, **send_kwargs)
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 649, in send
bot2_1    |     adapter = self.get_adapter(url=request.url)
bot2_1    |   File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 742, in get_adapter
bot2_1    |     raise InvalidSchema("No connection adapters were found for {!r}".format(url))
bot2_1    | requests.exceptions.InvalidSchema: No connection adapters were found for 'runner:5000/runnerhub/negotiate'
...
engine_1  | [INFO] [RunLoop]: Waiting for all bots to connect

So I suspect I’m still missing something in the compose YAML?

Thanks in advance

Hey @japes,

Sorry this one took so long to get back to you.

Looks to me like your bot is actually failing to connect when running in docker.
If I look at the last line your bot printed in its stack trace, you’ll see its connecting to runner:5000/runnerhub. Might be the way the library is printing the log, but it looks to me that there is no http being sent into that URL.

Can you try this again with the JS starter bot as your bot2, and let me know if the issue persists?

I get similar errors with the javascript bot (i.e. just replacing the build line to build: ../starter-bots/JavascriptBot) :

bot3_1    |
bot3_1    | > javascriptbot@1.0.0 start /app
bot3_1    | > node javascript_StarterBot.js
bot3_1    |
runner_1  | [DEBUG] [RunnerHub]: New Connection
bot3_1    | /app/node_modules/@microsoft/signalr/dist/cjs/HttpConnection.js:575
bot3_1    |             throw new Error("Cannot resolve '" + url + "'.");
bot3_1    |             ^
bot3_1    |
bot3_1    | Error: Cannot resolve 'runner:5000/runnerhub'.
bot3_1    |     at HttpConnection.resolveUrl (/app/node_modules/@microsoft/signalr/dist/cjs/HttpConnection.js:575:19)
bot3_1    |     at new HttpConnection (/app/node_modules/@microsoft/signalr/dist/cjs/HttpConnection.js:64:29)
bot3_1    |     at HubConnectionBuilder.build (/app/node_modules/@microsoft/signalr/dist/cjs/HubConnectionBuilder.js:117:26)
bot3_1    |     at Object.<anonymous> (/app/javascript_StarterBot.js:14:6)
bot3_1    |     at Module._compile (internal/modules/cjs/loader.js:1063:30)
bot3_1    |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
bot3_1    |     at Module.load (internal/modules/cjs/loader.js:928:32)
bot3_1    |     at Function.Module._load (internal/modules/cjs/loader.js:769:14)
bot3_1    |     at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
bot3_1    |     at internal/main/run_main_module.js:17:47
bot3_1    | npm ERR! code ELIFECYCLE
bot3_1    | npm ERR! errno 1
bot3_1    | npm ERR! javascriptbot@1.0.0 start: `node javascript_StarterBot.js`
bot3_1    | npm ERR! Exit status 1
bot3_1    | npm ERR!
bot3_1    | npm ERR! Failed at the javascriptbot@1.0.0 start script.
bot3_1    | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
bot3_1    |
bot3_1    | npm ERR! A complete log of this run can be found in:
bot3_1    | npm ERR!     /root/.npm/_logs/2021-04-07T18_18_19_004Z-debug.log

I may be misunderstanding the example in the README, perhaps the fields aren’t meant to be literal values, but should be substituted for something? I’ve tried http://localhost instead of runner and that results in:

bot3_1    |
bot3_1    | > javascriptbot@1.0.0 start /app
bot3_1    | > node javascript_StarterBot.js
bot3_1    |
runner_1  | [DEBUG] [RunnerHub]: New Connection
runner_1  | [INFO] [RunnerState]: Registering Engine
runner_1  | [DEBUG] [CloudCallback]: Cloud Callback called with Ready
runner_1  | [DEBUG] [CloudCallback]: Cloud Callback No-opped, Status: ready
bot3_1    | [2021-04-07T18:19:37.427Z] Warning: Error from HTTP request. FetchError: request to http://localhost:5000/runnerhub/negotiate?negotiateVersion=1 failed, reason: connect ECONNREFUSED 127.0.0.1:5000.
bot3_1    | [2021-04-07T18:19:37.428Z] Error: Failed to complete negotiation with the server: FetchError: request to http://localhost:5000/runnerhub/negotiate?negotiateVersion=1 failed, reason: connect ECONNREFUSED 127.0.0.1:5000
bot3_1    | [2021-04-07T18:19:37.428Z] Error: Failed to start the connection: FetchError: request to http://localhost:5000/runnerhub/negotiate?negotiateVersion=1 failed, reason: connect ECONNREFUSED 127.0.0.1:5000
bot3_1    | Disconnected

My docker knowledge is lacking …probably just a missing field in the yml, or something…? :man_shrugging:

Hi @japes,

We did indeed identify this one as an issue in the JS and Python bot.
If you look in the java or reference bot, they both substitute in the http:// if it is not present.
This is needed to deal with how the ip addresses and hostnames resolve on the containers, as well as in the cloud.

We have the issue on our radar and will have them updated in the next release.

In the meantime however, you can simply update the code that builds the url to start with http:// and then append the rest.

1 Like

Excellent, that sorts it out, thanks!

So that seems to sort out python and javascript bots, but I seem to still occasionally be seeing this:

Error while sending data: connection was stopped before invocation result was received

When running the cpp bot.
I just tried running a match 4 times in a row . It worked once, and at least one of the bots had the issues the other 3 times.
This was with 4 cpp bots in the yml.

Could it be a timing thing, the bot image sometimes starting up before the engine?

I have some logs files that I’ll send through via email.

Any pointers would be appreciated!

thanks

So it is very possible that the bot is starting up before the game engine. What I did for testing purposes was to create a 5s timeout in the main loop of the bot for testing locally.

However in the live production environment, we make sure everything is run in the correct order

Also something to note. I was experiencing some random and weird issues with the cpp bot randomly failing.

I was not sure what was causing the issue, however we can maybe run some extra diagnostics to see what is causing the issue.

There is also a signalr logging flag which can be used to increase verbosity

@raezor WRT Your comments on the Github PR for appending HTTP, I think this thread might be valuable for additional insight for you.

Feel free to reach out to me if you have any other questions on it though.