I’m having a horrible time with setting up my Docker configuration for my go service. Below is an overview of my setup
go_binary(
name = "main_arm64",
embed = [":server_lib"],
goarch = "arm64",
goos = "linux",
visibility = ["//visibility:public"],
)
container_image(
name = "ww_server_image",
base = "@go_image_static_arm64//image",
entrypoint = ["/main_arm64"],
files = [":main_arm64"],
ports = [
"8080",
"3306",
],
)
I have a GraphQL Playgroud (HTTP) running on http://localhost:8080
, and despite the port supposedly being exposed, i cant access the playground UI.
All I’m trying to do is:
- Be able to access the GraphQL playground and any other APIs running on other ports within the container
- Be able to make requests from my Dockerized Go app to a separate MySQL container (I can’t figure out how to put them on the same network with
rules_docker
). docker exec -it ... /bin/bash
into my docker container (this hasnt been working because bash isnt installed, yet i have no idea how to install bash via this container_image command)
Here is the error:
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown
If i take the generated docker image ID and run docker run -p 8080:8080 IMAGE_ID
, I’m able to access the GraphQL playground, but can’t communicate with the MySQL container
If I change the network as such: docker run --network=host -p 8080:8080 IMAGE_ID
the Dockerized Go app can successfully communicate with the MySQL container, but then the GraphQL playground becomes inaccessible. The GraphQL playground only becomes accessible if I maintain --network=bridge
. I’m not sure why MySQL isn’t using bridge
as well, since i never specified the network when starting it. This is how I got the MySQL container
docker run -p 3306:3306 --name my-db -e MYSQL_ROOT_PASSWORD=testing -d mysql:8.0.31
2
Answers
the answer was here: Unable to connect to mysql server with go and docker - dial tcp 127.0.0.1:3306: connect: connection refused
turns out i need to actually access MySQL using the following address, since Docker on Mac uses Linux VM:
So, you have several problems here:
First of all, you can most likely access containers that don’t have bash installed through
docker exec -it container_name /bin/sh
, as most containers at least come with sh.Second, your host machine can only have one service per port, so when you assign network host to a container, you overwrite the port mapping of other containers, which is why your GraphQL became unreachable after starting the go app with network host as a result of that they both use port 8080.
Third, when you use the default bridge network, your containers can only communicate by IP, not by container name.
Also, you don’t need a port mapping to let the containers communicate with each other. Port mapping is only required, when something outside the Docker network needs the access.
Your best chance is to create a network with
docker network create network_name
and then to assign the network to all containers with--network network_name
through the Docker run command.You don’t necessarily need a port mapping to get your application running, but when you want to access a service from outside – e.g. your hosts browser – make sure to take a unique port for each container. The port outside doesn’t have to be the same as the container’s internal port, you can map for instance
-p 8081:8080
.Since all containers belong to one app, you also might want to check whether docker compose is the better alternative as it allows you to easily manage all your container by one config file.