Search code examples
mysqldockerport

How do I avoid 'port collision' when using docker?


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?


Solution

  • In your docker-compose.yml file you are exposing ports from your pods on your hosts' network space by declaring them in the ports array, such as:

    ports:
      - "3306:3306"
    

    If you omit this part of the configuration, your containers will still be able to reach each other privately, but the ports won't be bound in your host machine, avoiding the port collision you are facing.

    If you require to expose your ports to the host for some or all your services, you'll have to handle the collisions yourself by changing the bound port on the host side. For instance, to avoid port collision on port 3306 you could simply do:

    ports:
      - "3307:3306"