Docker Compose: Bind for 0.0.0.0:3307 failed: port is already allocated

I have a Spring Boot that that connects to a MySQL DB. I’m trying to Dockerize it and create a docker-compose.yml that stands up a MySQL container and then stands up a Dockerized version of my Spring Boot app that can talk to it.

My project looks like this:

myapp/
  src/
    main/
      java/
        <All the Java code here>
      resources/
        application.yml
  build/
    libs/
      myapp.jar
  Dockerfile
  .env
  docker-compose.yml

When I run ./gradlew clean bootJar it builds a build/libs/myapp.jar.

My .env file:

MAIN_DB_HOST=127.0.0.1
MAIN_DB_PORT=3307
MAIN_DB_DOCKER_PORT=3306
MAIN_DB_USERNAME=root
MAIN_DB_PASSWORD=123456
MAIN_DB_ROOT_PASSWORD=123456
MAIN_DB_DATABASE=myapp_db

SERVER_PORT=9200
WS_PORT=9200
WS_DOCKER_PORT=9201

My Dockerfile:

FROM eclipse-temurin:11

RUN mkdir /opt/app

COPY app/build/libs/myapp.jar myapp

ENTRYPOINT ["java","-jar","myapp"]

My docker-compose.yml:

version: "3.8"

services:
  myapp_db:
    image: mysql:8.0.32
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=$MAIN_DB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MAIN_DB_DATABASE
      - MYSQL_CHARSET=utf8mb4
      - MYSQL_COLLATION=utf8mb4_0900_ai_ci
      - MYSQL_ENGINE=InnoDB
    ports:
      - $MAIN_DB_PORT:$MAIN_DB_DOCKER_PORT
    volumes:
      - db:/var/lib/mysql
  myapp:
    depends_on:
      - myapp_db
    build: .
    restart: on-failure
    ports:
      - $WS_PORT:$WS_DOCKER_PORT
      - $MAIN_DB_PORT:$MAIN_DB_DOCKER_PORT
volumes:
  db:

When I run ./gradlew clean bootJar && docker-compose --env-file .env up -d I see my Docker image get built but when it starts up I get:

WARNING: Image for service myapp was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating myapp_myapp_db_1         ... done
Creating myapp_myapp_db_1         ... 
Creating myapp_myapp_db_1         ... error

ERROR: for myapp_myapp_db_1 Cannot start service myapp: driver failed programming external connectivity on endpoint myapp_myapp_db_1 (33899c0810d03db26ef7b48e67328ea9eb4e0f75cebc0201e667db72ce21d7ba): Bind for 0.0.0.0:3307 failed: port is already allocated

ERROR: Encountered errors while bringing up the project.

Can anyone spot where I’m going awry?

>Solution :

You are trying to publish the same ports twice

services:
  myapp_db:
    ports:
      - $MAIN_DB_PORT:$MAIN_DB_DOCKER_PORT
  myapp:
    ports:
      - $MAIN_DB_PORT:$MAIN_DB_DOCKER_PORT

Having the same port number on the left-hand side of two ports: lines will cause the "port is already allocated" error you see. However, the ports: declaration routes network connections to a specific container; since myapp isn’t running a database, it doesn’t need that ports: line at all.

(The second ports: number is a fixed value for whatever image you’re running; for MySQL, it will always be 3306. I wouldn’t bother including this in a .env file. Also consider that ports: are not used or required for connections between containers and you may not need ports: for your database at all.)

You should delete the MAIN_DB_PORT line for your application, but make sure to leave the line that publishes your application’s port.

services:
  myapp_db:
    ports:
      - $MAIN_DB_PORT:3306  # optional
  myapp:
    ports:
      - $WS_PORT:9201       # probably required
#     - $MAIN_DB_PORT:3306  # <-- delete this one, causes the error

Leave a Reply