I hope the title is descriptive enough. I am trying to execute my node app (that uses mongo and mysql) in docker. I am using docker-compose
to start the app and docker-compose.yml
file below:
version: "3.3"
services:
app:
container_name: app
restart: always
build: .
volumes:
- ./:/app
ports:
- "3000:3000"
links:
- mongo
- mysql
mongo:
container_name: mongo
image: mongo
ports:
- "27017:27017"
mysql:
container_name: mysql
image: mysql
ports:
- "3306:3306"
Whenever I try to start this using docker-compose up
I get the following error:
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (785b03daaa662bb3c344025f89fd28f49eabb43104b1c9a16ab425ab5120309f): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use
ERROR: for mysql Cannot start service mysql: driver failed programming external connectivity on endpoint mysql (785b03daaa662bb3c344025f89fd28f49eabb43104b1c9a16ab425ab5120309f): Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use
ERROR: Encountered errors while bringing up the project.
I did a little bit of research and it seems that gitlab-runner
is using the mysql service. My understand was that if I run this setup through docker container they are isolated from the host system so I won't have any port conflicts. The only ports that I am exposing are the ones in my Dockerfile
- in my case 3000. Am I missing something in my docker-compose.yml
? What else could be wrong?
By default, when you create or run a container using docker create or docker run , it does not publish any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers which are not connected to the container's network, use the --publish or -p flag.
Surprisingly or not, neither Docker nor Podman support exposing multiple containers on the same host's port right out of the box. Example: docker-compose failing scenario with "Service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash."
When you open the browser and navigate to the Docker host on port 8080, you will see Jenkins up and running.
Docker Network bypasses Firewall, no option to disable Check the firewall; docker will by use "anywhere" as the source, thereby all containers are exposed to the public.
Stop binding to local ports and let docker-compose
pick an ephemeral port for you. In your case, your application can get to the default ports without any help. If you are following the 12 Factor App approach, then use environment variables like in the following snippet.
version: "3.3"
services:
app:
restart: always
build: .
volumes:
- ./:/app
ports:
- 3000 # will be bound to an ephemeral port
environment:
MONGODB_URL: mongodb://mongo/db # can reach port 27017 without help
mongo:
image: mongo
ports:
- 27017
This is the primary reason to make your applications configurable via environment variables or command-line flags.
You can use docker-compose port to get the ephemeral port if you need to access a docker application from the host. I routinely use a shell function like the following:
get_exposed_port() { # SERVICE PORT
docker-compose port $1 $2 | cut -d: -f2
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With