Connecting native Database-Client to Docker SQL-Container using Docker-Toolbox

Attention: This post only handles "Docker Toolbox". If possible use "Docker for Windows"! "Docker Toolbox" is a workaround for Windows Home that doesn't provide the "Hyper-V"-Feature.

In one of our projects, my team is developing a new dockerized plattform. Dockerized means, that we split the infrastructure into seperate images like web, php and database. My team is developing on the ubuntu os with a native docker client. I’m working on a windows 10 using the docker-toolbox.
Overall we have central docker-compose scripts to combine all images to one working infrastructure. Following a snippet of our database (mariadb) composer configuration:
mysql:
    image: mariadb:10.1
    ports:
      - "127.0.0.1:3306:3306"
    environment:
      MYSQL_DATABASE: <projectname>
      MYSQL_ROOT_PASSWORD: pw
    volumes:
      - <projectname>-mysqldata:/var/lib/mysql
    networks:
      - back
    logging:
      options:
        max-size: "25m"
        max-file: "4"
The team is used to work directly on the host operating system (ubuntu). The database client (mysql-workbench) and the nginx is configured to connect into the docker containers, so that they don’t need to login into an container to get for example database table information.

Problem

On setting up my development environment on windows using docker-toolbox, I was not able to connect my native database client MySql-Workbench to the docker-container.
Trying to connect, I got the following error message:
Failed to Connect to MySql at 127.0.0.1:3306 with user root. Can’t connect to MySQL server on ‘127.0.0.1’ (10061)
Checking my running docker containers with docker ps I got the followng response so that I was assured, that my containers run smoothly:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a3ce48f0038 mariadb:10.1 “docker-entrypoint.s…” Up 3 hours ago Up 3 hours 127.0.0.1:3306->3306/tcp myproject_mysql_1
With docker exec -it myproject_mysql_1 bash I was able to switch into the sql docker container.

Background

To understand the issue, it’s necessary to understand, how docker-toolbox works. Facing some challanges creating a native docker for windows, the docker-toolbox has been developed.
This toolbox has a, lets call it “workaround”, with large effects on the scenario described above:
Starting the docker-toolbox-terminal, a virtual machine is created in the background (with VirtualBox), running the docker containers. So, the setup looks more or less as stated in the following graph:
Having in the background the virtual machine, also the standard localhost IP address changes to a variable one. Starting the docker-toolbox-termial, the new IP address is displayed:

Solution

Knowing that background, the solution was quite easy. I only needed to adjust IP address of the compose file from ‘127.0.0.1:3306’ to my variable IP address the docker-toolbox-terminal gave me:
mysql:
    image: mariadb:10.1
    ports:
      - "192.168.99.101:3306:3306"
    environment:
      MYSQL_DATABASE: eventerza
      MYSQL_ROOT_PASSWORD: pw
    volumes:
      - eventerza-mysqldata:/var/lib/mysql
    networks:
      - back
    logging:
      options:
        max-size: "25m"
        max-file: "4"
After changing the compose file and restarting my docker containers, I tried to connect to my database using MySql-Workbench and the new IP address again and look, it worked.

Alternatively the 127.0.0.1 mapping can be removed and an /etc/hosts entry added in windows:
192.168.99.101    localhost    myproject.dev

The advantage of removing the IP from compose file and adding a hosts entry is, that the database can be connected without trouble.
The disadvantag is, that normally the database should only be available within the docker network and not from outside. Doing it that way, the database container is reachable from outside.

Assuming, that for local development the fact that the mysql is accessable from outside doesn't care, you can also split the compose files in the following ones:

  • docker-compose.yml (basic script)
  • docker-compose-prod.yml
Starting the dev environment only the docker-compose.yml is needed. Starting the prod environment, the docker-compose-prod.yml needs also to be added. The prod file then overwrites the ports of the docker-compose.yml by the 127.0.0.1.

# docker-compose  -f docker-compose.yml -f docker-compose-prod.yml up -d

Conclusion

So, comming to my conclusen. I’m quite happy that I solved that issue. But in my opinion, this solution is not practicable for the real development. First, I don’t want to change the docker-compose files always when I get a new IP. Second, if everyone does it the same way, the project runs into a complete chaos.
If you have a different opinion on that or have any suggestions how to solve that issue with docker-toolbox, please let me know and give a short comment.
This Blog-Post references to our Stackoverflow discussion (Link). Many thanks to tgogos for the good support.

Comments

Popular posts from this blog

Creating a simple api mock service in Aurelia-cli

How to create a custom Task using Aurelia-CLI