Vishakha Lall
Vishakha Lall

Reputation: 1314

Unable to connect to mysql container defined in docker-compose using service name

I have the following docker-compose.yml

version: '3'
services:
  app:
    build: .
    network_mode: host
    volumes:
      - .:/usr/usr/src/app
  db:
    image: mysql/mysql-server:5.7
    environment: 
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    volumes:
      - ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
    restart: always
    ports:
      - "1200:3306"

My app service needs to connect to the db and using the documentation I tried to connect to using the service-name 'db' like so (from the app container) mysql --hostname=db --port=3306 --user=root However, I get the error ERROR 2005 (HY000): Unknown MySQL server host 'db'

What am I doing wrong?

Upvotes: 0

Views: 1629

Answers (3)

Delta George
Delta George

Reputation: 4236

Because of network_mode: host your app container is effectively on a docker's private network like 192.168.65.1/24 while you db container is on a different private network created by docker-compose like 172.20.0.2/16. You can see this network being deleted when you run docker-compose down:

Removing network XXXX_default

where XXXX is your directory name.

If you were to remove network_mode: host from service app, both containers would be on the same private network and reachable by their service name.

$ docker inspect XXXX_default

    "Containers": {
            ...
            "Name": "app",
            "IPv4Address": "172.21.0.3/16",
            ...
        },
            ...
            "Name": "db",
            "IPv4Address": "172.21.0.2/16",
            ...
        }
    },

app container can access db on port 3306. No need to expose the port as 1200. As per docs:

Containers connected to the same user-defined bridge network automatically expose all ports to each other, and no ports to the outside world. This allows containerized applications to communicate with each other easily, without accidentally opening access to the outside world.

Upvotes: 1

David Maze
David Maze

Reputation: 159865

Your app container is running with network_mode: host. If it's using the host network then it can't use any of the Docker-specific network features; for example, it can't reach other containers by host name and it can't be reached by host name. For Docker networking purposes it's indistinguishable from a process running on the host.

Host networking isn't actually necessary for most of the cases I see suggested on SO, and you should see if your application works if you just remove that line. You might need to add ports: to make it accessible from outside.

If you really can't disable host networking, then you need to connect to the database the same way other processes running outside Docker network space would, via the other container's published ports. A host name of localhost should work (because you're in the context of the host) but you need the mapped port number --port=1200.

Upvotes: 1

Aleksandr
Aleksandr

Reputation: 431

Add links configuration in app section

version: '3'
services:
  app:
    build: .
    network_mode: host
    volumes:
      - .:/usr/usr/src/app
    links:
      - db
  db:
    image: mysql/mysql-server:5.7
    environment:
      MYSQL_DATABASE: config_dev
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    volumes:
      - ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
    restart: always
    ports:
      - "1200:3306"

Upvotes: 1

Related Questions