0

I use docker-compose to wire up mysql container view detail

I want to connect to it using container name as host, but connection denied.
Using host=localhost can get thru though.

My google search and search on our stackoverflow only give result that point to using internal IP e.g. this post which I'm not looking for.

So my question is how to use docker container name as mysql host when connect?

Nam G VU
  • 33,193
  • 69
  • 233
  • 372
  • 1
    From [this](https://stackoverflow.com/questions/44991743/docker-connecting-php-container-to-mysql). Your db container service name `mariadb`(mentioned as service name in docker compose link you provided) should do fine. – Umair Khan Sep 12 '20 at 10:18
  • Can you use an environment variable or another mechanism to make the host name configurable? That'd support a variety of setups (local development, Docker Compose, Kubernetes, cloud-hosted databases). – David Maze Sep 12 '20 at 11:18
  • @DavidMaze Could be more helpful as you can give more details on using env var for host name access – Nam G VU Sep 12 '20 at 13:32
  • @UmairKhan I'm not calling from container to container. I'm querying from host os to mysql container – Nam G VU Sep 12 '20 at 13:33
  • Configuring your application to use an environment variable is pretty language- and framework-specific, but it should be pretty easy to look up the correct syntax. – David Maze Sep 12 '20 at 14:57

1 Answers1

0

Update: As pointed out by David Maze, the solution is OS Host specific dependant.

The OP never mentioned his Host type at the time of answering, so this solution I created is for a Linux OS host/Linux Container (and works with the OP's mariadb image).

To answer the question of container name:

There seems to be no direct way for the host to be aware of the container name itself, but docker-compose does create cpe-* entries into the firewall automatically for multi-service docker-compose projects. NOTE: These cpe entries are auto-named, and I am not aware of any way of changing those names*`

These entries resolve to the internal container IP when you ping them from the host, so you can use them instead of container name.

HOWEVER, Since this is a singular service docker-compose project (only MariaDB), it seems Docker does not create those entries automatically. You will have to create a manual host entry inside /etc/hosts so that it can resolve to container IP. Read on....

Assuming you use that docker-compose.yml with your up.sh, this is how was able to connect to a new Docker container created (from your project linked). I was able to connect to the MySQL container instance from the Host.

Before the container could even start (show nothing in docker ps), I saw that the port is 3306, it failed to start at first - because I already have a MySQL instance on that port, so this made it easy to find port!

Steps

I removed the volumes section because I don't know how they interact with your container

After running up.sh:

$ docker ps
7c13bf1855a0        bitnami/mariadb:10.3      "/opt/bitnami/script…" 4 minutes ago    Up 4 minutes   0.0.0.0:3306->3306/tcp 
 nn_mariadb

I see a new network created:

$ docker network ls
86d2c3211505        mariadb_default                   bridge              local

docker network inspect mariadb_default
(PARTIAL ONLY): 

 "Containers": {
            "7c13bf1855a083f4cba3071edc03b671346a9e8efbe60b6b4d9585113b542020": {
                "Name": "nn_mariadb",
                "EndpointID": "603851d3e134aedef126febb0c30786a5564cccd4f3803cfe965a80ed747df7a",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },

This means the IP Address of the new container is 172.18.0.2

Verify with ping on host to container IP:

myuser@myserver:/var/www/docker/stackoverflow.help/mariadb$ ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.104 ms

Entering the container: The container does not have ping etc to verify network, but it worked as described below

docker exec -ti nn_mariadb bash

I have no name!@7c13bf1855a0:/$ mysql -u root -p -h 172.18.0.2 -P 3306
MariaDB [(none)]>

From the host to the container:

myuser@myserver:/var/www/docker/stackoverflow.help/mariadb$ mysql -u root -p -h 172.18.0.2 -P 3306
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 5.5.5-10.3.24-MariaDB Source distribution

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

mysql>

Finally:

NOTE: I assume that your host generates the firewall entry automatically based on this : 0.0.0.0:3306->3306/tcp nn_mariadb

Firewall may interfere if port 3306 does not want to connect as I did above.

Can container name be used directly?

It does not seem the host is directly aware of the container name. Some docker-compose projects do add items into the firewall like this :

ACCEPT     tcp  --  anywhere cpe-172-100-0-2.twcny.res.rr.com  tcp dpt:http
ACCEPT     tcp  --  anywhere cpe-172-100-0-3.twcny.res.rr.com  tcp dpt:6379
ACCEPT     tcp  --  anywhere cpe-172-100-0-5.twcny.res.rr.com  tcp dpt:http-alt
ACCEPT     tcp  --  anywhere cpe-172-100-0-4.twcny.res.rr.com  tcp dpt:6082
ACCEPT     tcp  --  anywhere cpe-172-100-0-4.twcny.res.rr.com  tcp dpt:6081

I assume it only relates to multi-service docker-compose projects

However, these cpe-* names are auto-generated even if you customize your docker network. You can then connect via this name because it resolves to the container IP.

As mentioned above, it seems it only creates entries like those into the firewall when multi-service docker-compose projects are done, with this singular container it only creates:

ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:mysql

What can I do when these entries are not generated?

TLDR: You cannot use the container name automatically - you will have to create a custom entry.

Add the entry into your host etc/hosts file:

172.18.0.2  maria_db_host

Then:

$ mysql -u root -p -h maria_db_host -P 3306
CvRChameleon
  • 367
  • 1
  • 5
  • 29
  • Thanks for details and showing that we use the **internal IP** to access. I'm looking for way to use container name. – Nam G VU Sep 12 '20 at 13:34
  • 1
    The container-internal IP address is only accessible on one specific Docker/host OS combination: it will not work at all on MacOS, or Windows, or if Docker is in a VM, or if you're on a different host. I would not recommend looking it up. – David Maze Sep 12 '20 at 14:55
  • 1
    True, but lacking the information provided in original question of which host I had to show one solution, this will be useful to someone in the future. – CvRChameleon Sep 12 '20 at 14:59
  • 1
    @NamGVU I read your question originally and saw that you wanted to use the container name, I forgot to answer the part directly, **there seems to be no direct way to use container name itself from host**. However, I updated my answer, please read the bottom part for extra information. Maybe you can then decide if you want to use that method/or IP, as both ways are `manual ways` for an alternate solution. – CvRChameleon Sep 12 '20 at 15:26
  • @DavidMaze You did make sense. How about we narrow it to linux/ubuntu env only? – Nam G VU Sep 13 '20 at 06:31
  • @CvRChameleon Thanks for comment. I have update my OP to amplify "not internal IP" – Nam G VU Sep 13 '20 at 06:33
  • Thanks CvRChameleon and @David Maze, I've updated my OP to amplify linux environment – Nam G VU Sep 13 '20 at 06:36
  • With your thougtfully and carefully explaination, I think that's a perfect accepted answer @CvRChameleon! – Nam G VU Sep 13 '20 at 06:40
  • Thanks. Its unfortunate that container name itself does not resolve to internal IP. I assume it's because in Docker system containers and networks are separate entities ( for good reason), those autogenerated virtual host entries added to firewall could have been useful if they could be named the same as container name in docker-compose. I will test the exact conditions where they are autogenetated and if found will update my answer ... might be useful for someone. – CvRChameleon Sep 13 '20 at 07:22