Connect to remote MySQL db from docker container - mysql

I'm working to containerize a Django 1.5.x application that connects to a MySQL DB on a separate server via ODBC:
[mysql_default]
database = DB_NAME
driver = /usr/lib64/libmyodbc5.so
server = REMOTE_DB_SERVER
user = DB_USER
password = DB_USER_PWD
port = 3306
I'm able to run the Django app on my local machine (outside docker) with a connection to the remote DB via port forwarding & SSH:
ssh -L 3307:127.0.0.1:3306 MYID#REMOTE_DB_SERVER
I've set up a Docker container for the app using Centos 6.x, but can't get the MySQL connection working. The container has MySQL installed and the mysqld running.
My docker-compose.yml file looks like this:
version: "2"
services:
web:
build: .
image: MY_IMAGE
container_name: MY_CONTAINER
network_mode: "host"
ports:
- "3307:3306"
command: /bin/bash
With the container running, I can execute the following command (outside the container) to show databases on the remote DB:
docker exec MY_CONTAINER echo "show databases" | mysql -u DB_USER -pDB_USER_PWD -h 127.0.0.1 --port=3307
But from inside the container the same command fails:
echo "show databases" | mysql -u DB_USER -pDB_USER_PWD -h 127.0.0.1 --port=3306
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1' (111)

The Docker works like a virtual machine. It has a local storage and a local environment. When you connect to 127.0.0.1 from the Docker it tries to connect to this Docker (not to local machine where the Docker was runned) because the localhost for the Docker is the Docker.
Please, read the following answer:
From inside of a Docker container, how do I connect to the localhost of the machine?

I solved this by using the docker host address instead of '127.0.0.1' for queries from within the container:
echo "show databases" | mysql -u DB_USER -pDB_USER_PWD -h 10.0.2.2 --port=3306
Because Docker host ip can vary, this post describes steps to get the right address:
How to get the IP address of the docker host from inside a docker container

I've created a bridge network:
$ docker network create -d bridge mynetwork
After, see the IP and port
$ docker inspect mysql
...
"Ports": {
"3306/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "32031"
}
],
"33060/tcp": null
}
...
Connect with 0.0.0.0:32031
Solved by Basit

Related

Spring boot dockerized cannot reach MySQL

I dockerized a MySQL database by doing:
docker pull mysql
docker run --name=container_name -p 3307:3307 -e MYSQL_ROOT_PASSWORD=password -d mysql
Now the container <container_name> is the only one I have in Docker, and its network is set by default to "bridge".
Using: docker exec -it container_name mysql -u root -p (then typing the password) I created a brand new database.
I tried reaching that database from my SQL client, using the specified credentials and database url:
server: localhost or container_name, port: 3307, user: root, password: password.
The client doesn't reach the database and I get the following errors:
Connection refused: connect
Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
Obviously I get the same error while running my spring boot application (not dockerized yet), but the problem is something in MySQL container since the SQL client isn't working as well.
I've been reading countless questions same as mine, but the solutions that they offer, never work for me.
What's weird is the fact that in the past projects it worked fine.
I'm running Docker on Windows 10 Pro with Hyper-V.
If you're trying to connect from outside of Docker, your docker run -p option is wrong: the second port number always needs to be the standard port number of its service. For MySQL, that second port number needs to be 3306, always. The two port numbers need to match.
docker run -d -p 3307:3306 ... mysql
# ^^^^
# must be the standard port number
If you're trying to connect from inside Docker, then
You must docker network create a network, and docker run --net all involved containers on that network
You must use the other container's name as a host name, not localhost
You must use the standard port number, again 3306; docker run -p options are ignored (and aren't required)
docker network create some-net
docker run -d --net some-net --name database \
-p ... -e ... -v ... \
mysql
docker run -d --net some-net --name application \
-e MYSQL_HOST=database \
-e MYSQL_PORT=3306 \
my/application
If you're running this under Docker Compose, it automatically creates the network for you, and you can use the Compose service name as the host name. You do not need to manually set up networks: or override the container_name:.
version: '3.8'
services:
database:
image: mysql
# ports: [...]
# environment: [...]
# volumes: [...]
application:
build: .
environment:
MYSQL_HOST: database
MYSQL_PORT: '3306'

How to run a MySQL command terminal in Docker, with a docker-compose server

Let's say I have the following compose file :
networks:
my_network:
services:
...
mysql:
container_name: "mysql"
image: "mysql:5.7"
volumes:
- ./mysql.cnf:/etc/mysql/conf.d/mysql.cnf
environment:
MYSQL_ROOT_PASSWORD: "password"
MYSQL_USER: "user"
MYSQL_PASSWORD: "password"
MYSQL_DATABASE: "test-db"
ports:
- "3306:3306"
restart: always
networks:
- my_network
Once I run docker-compose up, my services get started and I can see that my MySQL server is ready to accept connections. Now what do I need to do to access the mysql terminal prompt from "outside" the container ? I remember seeing a teacher run another docker container (from a new terminal), and access the MySQL command prompt, enabling him to manage the database by hand, from another terminal window, but I can't remember the command exactly.
I tried running a new Docker container like this :
docker run -it --rm --name mysqlterm \
--network="compose_project_my_network" \
--link mysql mysql:5.7 \
sh -c 'exec mysql \
-h "localhost" -P 3306" \
-uroot \
-ppassword'
But unfortunatly, the container can't connect to the MySQL server, giving me the following error : ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2).
I guess the "localhost" or 3306 port are wrong ? What should I put in these parameters ?
Thanks in advance for your answers :)
You need an ordinary MySQL client; if your host's package manager (Debian/Ubuntu APT, MacOS Homebrew, ...) has a packaged named something like mysql-client, that's it.
When you run mysql, that tool does not interpret localhost as a host name but rather as a signal to use a Unix socket, so you need to use the corresponding IP address 127.0.0.1 instead. (If the database is running on a different system, use its DNS name or IP address: this is indistinguishable from running the database directly on the host outside of Docker.)
So from the host run:
mysql -h 127.0.0.1 -u root -p
The default port 3306 matches the published ports:, and you'll be prompted to interactively enter the password.

Connect to a mysql server running in a docker container from another container?

I have two containers; a node.js server, and a mysql server ...
Both are running fine, I'm trying to connect to the database running in the MySQL container from my node app.
I've created a bridge network:
$ docker network create -d bridge mynetwork
and run both of my containers in this network with:
$ docker run -p 32031:3306 --network mynetwork --name mysql -e MYSQL_ROOT_PASSWORD=abc123 -d mysql:5.7
$ docker run -p 3000:3000 --network mynetwork node-server node index.js
I'm trying to connect with the IP of the mysql container that I found with docker inspect mysql, which is 172.18.0.2 and port 32031.
Where did it go wrong, it's not connecting?
If you connect by IP which you get from docker inspect command. That mean your connection now is 172.18.0.2 and port still 3306
Another way to connect from nodejs (nodejs and mysql in same network). Connect information is:
hostname: mysql // container name
port: 3306
Docker containers connected via a network can communicate internally. Your mysql container is running on port 3306 internally and 32031 externally.
Try connecting via port 3306. It should work.
Ohh, my good luck.
It's working now. I rebuilt the docker image and connected to the database with the IP that I found with inspect mysql container, and with port 32031.
Run docker container same as: $ docker run -p 3000:3000 --network mynetwork node-server node index.js
var pool = mysql.createPool({
connectionLimit : 3,
host : '172.18.0.1',
user : 'root',
port : 32031,
password : 'abc123',
database : 'mydatabase',
charset : 'utf8mb4',
timezone : 'PKT',
timeout : 4000
});

How to connect mysql docker container to node.js server or workbench

Iam beginner to docker and iam working on mysql and node.js I run mysql docker container as
docker run --name docker-mysql -e MYSQL_ROOT_PASSWORD=abc123 -d mysql:latest
and result of docker ps is showing mysql container is running
and docker logs says
MySQL init process done. Ready for start up.
how to connect with this container in workbench or in my application
Try this:
docker run -p 3306:3306 --name docker-mysql -e MYSQL_ROOT_PASSWORD=abc123 -d mysql:latest
This will bind the port 3306 on your local machine to the docker image. You should be able to connect to the database with localhost & port 3306 with username root and password abc123.
I just tested it and it works like a charm.
If you are struggling with the error:
failed to connect to localhost at 33016" details = Authentication
plugin 'caching_sha2_password' cannot be loaded:
dlopen(/usr/local/mysql/lib/plugin/caching_sha2_password.so, 2): image
not found
Update your MySQL-workbench.
If that doesn't work you will need to add a native password to the root user. Here is how:
Connect to your docker image via bash:
docker exec -it docker-mysql bash
Log into mysql as root
mysql --user=root --password
Enter the password for root (Default is 'root', but 'abc123' in this example)
Finally Run:
ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'abc123';
You need to expose the port
Use -p, or -P
-p is bound to a custom port, -P will randomly assign a port to you.
:latest does not need to add, docker will help you add.
The final command should look like this:
docker run -dit -P --name docker-mysql -e MYSQL_ROOT_PASSWORD=abc123 mysql:latest
Then use xx to see the exposed ports:
docker port docker-mysql
Check which port of the machine is mapped to port 3306 of the container, My result is:
33060/tcp -> 0.0.0.0:32818
3306/tcp -> 0.0.0.0:32819
Now you can connect to this port via software or code.
For development best way is to connect the container to "host" network
docker run --name docker-mysql --network host -e MYSQL_ROOT_PASSWORD=abc123 -d mysql:latest
When you will move to staging/prod environment consider to use some orchestration solution.
Run docker inspect container_id its will show container port but will not show host port bind. By Default running without -p flag it will assign port to container but will not expose host port , so to achieve this you shout try -p flag, -p 3306:3306 in docker run command.

Unable to connect to Mysql hosted on Docker on Windows machine

I already executed mentioned here: Unable to connect to MYSQL from Docker Instance, but this time I'm running docker on windows machine.
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker pull mysql/mysql-server
Using default tag: latest
latest: Pulling from mysql/mysql-server
e64f6e679e1a: Pull complete
799d60100a25: Pull complete
85ce9d0534d0: Pull complete
d3565df0a804: Pull complete
Digest: sha256:59a5854dca16488305aee60c8dea4d88b68d816aee627de022b19d9bead48d04
Status: Downloaded newer image for mysql/mysql-server:latest
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
79ff1c03452ab2eac0d798b576ffeabde24d4c5aa6954d3d5c5bef99dcc40ce8
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ mysql -uroot -ppassword
bash: mysql: command not found
pc#DESKTOP-NQ639DU MINGW64 /c/Program Files/Docker Toolbox
$ docker exec -it mysql bash
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2# mysql -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
bash-4.2#
You should try to connect through the loopback interface, as you don't have access to the socket.
mysql -h 127.0.0.1 -uroot -p
In this case, it's like if your server is running on another machine, this only thing share with your host machine is the exposed port.
If you download the MySQL client from https://dev.mysql.com/downloads/windows/ then you'll be able to access the Docker-hosted MySQL in the same way you'd access any other MySQL database (of note without needing to get a root shell in the database container). Since you're using Docker Toolbox you'd probably use 192.168.99.100 as the IP address of the database server.
Try adding below in docker-compose.y\ml
services:
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: 'Dbname'
# So you don't have to use root, but you can if you like
MYSQL_USER: 'username'
# You can use whatever password you like
MYSQL_PASSWORD: 'Password'
# Password for root access
MYSQL_ROOT_PASSWORD: 'RootPassword'
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3307:3306'
expose:
# Opens port 3306 on the container
- '3306'
# Where our data will be persisted
volumes:
- my-db:/var/lib/mysql
volumes:
my-db: