How to connect to MySQL running on Docker from the host machine - mysql

I have already googled on this subject and found few threads. Based on these threads I have followed the following steps. But I am facing a problem.
Basically, I want to create a docker image for mysql and then connect to it from my host machine (Mac OS X).
Based on this post , I have to share the mysql unix socket with the host. towards this I have done the following steps
1. Start docker quick terminal
2. docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
3. docker exec -it mysql bash
4. mysql -uroot -p
5. create database MyDB;
6. GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' IDENTIFIED BY 'password';
7. exit;
8. mkdir /Users/abhi/host
9. docker run -it -v /host:/shared mysql/mysql-server:latest
Now I get the error
MacBook-Pro:~$ docker run -it -v /Users/abhi/host:/shared mysql/mysql-server
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
But you see that I have provided the password and initialized my database.
All I want is that from my host machine, I can connect to the mysql database running inside docker.
EDIT:: ----- solution which worked ------
Thanks RICO. Finally the steps which worked for me are
1. Start docker quick terminal
2. docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
3. docker exec -it mysql bash
4. mysql -uroot -p
5. create database MyDB;
or:
CREATE USER 'root'#'%' IDENTIFIED BY 'root';
GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' WITH GRANT OPTION;
6. GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' IDENTIFIED BY 'password';
7. exit;
8. docker-machine env default
Use the IP address obtained in step 8. port is 3306, user is root, password is password, database is MyDB.
Connection is successful!

So you basically you need to expose the mysql port to your host:
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:latest
Then you can access from your host using the mysql command line:
mysql -h127.0.0.1 -ppassword -uroot
Not sure why you are trying to run another container to connect (perhaps you meant linking two containers)
If you are using Mac (or Windows) with docker-machine you want to connect to the IP address of your docker-machine VM. For example:
$ docker-machine ssh default
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
_ _ ____ _ _
| |__ ___ ___ | |_|___ \ __| | ___ ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__| < __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.9.0, build master : 16e4a2a - Tue Nov 3 19:49:22 UTC 2015
Docker version 1.9.0, build 76d6bc9
docker#default:~$ ifconfig eth1
eth1 Link encap:Ethernet HWaddr 08:00:27:E6:C7:20
inet addr:192.168.99.100 Bcast:192.168.99.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fee6:c720/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18827 errors:0 dropped:0 overruns:0 frame:0
TX packets:10280 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1791527 (1.7 MiB) TX bytes:2242596 (2.1 MiB)
Then connect to:
mysql -h192.168.99.100 -ppassword -uroot

docker run -e MYSQL_ROOT_PASSWORD=pass --name sql-db -p 3306:3306 mysql
docker exec -it sql-db bash
mysql -u root -p

Related

Cannot find mysql docker data files on my volume local host

I created a simple mysql docker instance as
docker run -d
--name mysql3
-p 3306:3306
-v db:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=rsecret
-e MYSQL_DATABASE=mkt_data_db
mysql/mysql-server:8.0
After that I logged in and created tables
$docker exec -it mysql3 bash
#mysql -u root -p
use mkt_data_db;
create table price (ticker char(30), eod_date date, close float);
insert into price(ticker, eod_date, close) values ('xyz', curdate(), 100.1);
When I logout and check db directory, its empty
$ ls -al db/
total 0
drwxr-xr-x 2 accnt staff 64 21 Jun 23:38 .
drwxr-xr-x 6 accnt staff 192 21 Jun 23:38 ..
when I stop+rm+run docker again, I do see the the 'price' table and the data within it
Where is the database stored on my local host (mac)?
I would ideally like to move these database files (data) to another computer, provide new DB volume on docker run there and see the data on that machine.
This is an interesting problem, and kudos to you for posting the answer!
I'd be curious to know what the result of docker inspect mysql3 would show (look for the "Mounts" section in the large amount of output) when NOT specifying the full path (like in your original question).
An afterthought: I like to use pwd when creating a shared volume (assuming you are running the command in the desired directory):
docker run -d
--name mysql3
-p 3306:3306
-v $(pwd):/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=rsecret
-e MYSQL_DATABASE=mkt_data_db
-e MYSQL_USER=mkt_data_usr
-e MYSQL_PASSWORD=usecret
mysql/mysql-server:8.0
The above problem was solved by providing absolute path with -v flag
i.e.
docker run -d
--name mysql3
-p 3306:3306
-v /Users/accnt/db:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=rsecret
-e MYSQL_DATABASE=mkt_data_db
-e MYSQL_USER=mkt_data_usr
-e MYSQL_PASSWORD=usecret
mysql/mysql-server:8.0
i.e. change -v db:/var/lib/mysql to -v /Users/accnt/db:/var/lib/mysql
After that $ls -l /Users/accnt/db showed my entire db contents (including mkt_data_db and price table inside

Cannot connect to mysql running in docker container from another

I know this seems like a common situation but nothing which I've found helps.
I'm following the docker 'getting-started' guide verbatim, literally copy and pasting the commands. But when I get to this step:
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:12-alpine \
sh -c "yarn install && yarn run dev"
The log output is as follows:
{ Error: connect EHOSTUNREACH 172.18.0.2:3306
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)
errno: 'EHOSTUNREACH',
code: 'EHOSTUNREACH',
syscall: 'connect',
address: '172.18.0.2',
port: 3306 }
Here is the catch, I can successfully connect to mysql running in the container from the host system:
$ mysql -h172.18.0.2 -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 8.0.27 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
Furthermore from the 'app' container, I can successfully ping the 'mysql' host. 'nc' is unable to connect though:
[mmorsi#localhost app]$ docker exec e8df2d36914 ping -c 3 mysql
PING mysql (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.071 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.173 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.176 ms
--- mysql ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.071/0.140/0.176 ms
[mmorsi#localhost app]$ docker exec e8df2d36914 nc -z -v mysql 3306
nc: mysql (172.18.0.2:3306): Host is unreachable
Other things I've tried:
Running the latest mysql docker image
Running the 'app' on the centos:latest image (with the necessary steps to install deps)
My host system is Fedora 33. On the host, the docker0 interface is running in the 'trusted' zone (target: ACCEPT):
[mmorsi#localhost app]$ sudo firewall-cmd --get-active-zones
FedoraWorkstation
interfaces: enp0s31f6
trusted
interfaces: docker0
[mmorsi#localhost app]$ man firewall-cmd
[mmorsi#localhost app]$ sudo firewall-cmd --info-zone=trusted
trusted (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: docker0
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
I'm all out of ideas. Any help or insights would be highly appreciated.
Figured it out!
(Courtesy of https://fedoramagazine.org/docker-and-fedora-32/)
A simple:
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-masquerade
So as to allow docker to make local connections was all that was needed! (in addition to the other steps listed there which I had previously run).
[Proceeds to pat self on back]

Docker with apache2/php5 cannot connect to mysql on host machine

I am trying to spin up a container to run a legacy webapp that needs php5.3. I want the container to access the mysql server on the host (i.e., the computer hosting the docker container). The mysql server is confirmed up and running, and I can log into it from the host computer.
My Dockerfile looks like this:
FROM ubuntu:12.04
VOLUME ["/var/www"]
VOLUME ["/etc/ssl"]
RUN apt-get update && \
apt-get install -y \
apache2 \
php5 \
php5-cli \
libapache2-mod-php5 \
php5-gd \
php5-ldap \
php5-mysql \
php5-pgsql
COPY ./apache2.conf /etc/apache2/apache2.conf
COPY ./000-default.conf /etc/apache2/sites-available/000-default.conf
COPY ./site1 /etc/apache2/sites-available/site1
COPY ./site2 /etc/apache2/sites-available/site2
COPY ./apache2-foreground.sh /var/apache2-foreground.sh
RUN a2ensite site1
RUN a2ensite site2
RUN a2enmod rewrite
RUN a2enmod ssl
EXPOSE 80
EXPOSE 443
CMD ["bash", "/var/apache2-foreground.sh"]
The apache2-foreground.sh script comes from here.
I deploy the container using this command:
docker run --detach \
--name legacy-php5.3 \
--net="host" \
-p 80:80 \
-p 443:443 \
-v /etc/ssl:/etc/ssl \
-v /var/www:/var/www \
my/php5.3
The --net="host" argument, if I understand correctly, should make the host's localhost accessible to the container. However, the container cannot connect to the mysql server on the host. The php command echo mysql_error() tells me Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2).
If I "ssh" into the container, and run $ mysql -h localhost -u <my_user> -p, then it tells me ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2).
On the host computer, the socket file is there:
$ ls -l /var/run/mysqld/mysqld.*
-rw-r----- 1 mysql mysql 6 Sep 6 12:16 /var/run/mysqld/mysqld.pid
srwxrwxrwx 1 mysql mysql 0 Sep 6 12:16 /var/run/mysqld/mysqld.sock
-rw------- 1 mysql mysql 6 Sep 6 12:16 /var/run/mysqld/mysqld.sock.lock
What am I doing wrong?
localhost is the unix socket within the container and not a tcp connection to the localhost IP address. To access the unix socket on the host you'd need -v /var/run/mysqld:/var/run/mysqld to map the socket on host into the container. You'll also need VOLUME /var/run/mysqld in the Dockerfile.
Alternately use TCP by specifying 127.0.0.1 as the host for your application along with --net="host" in the docker run command line.
Yes, you understand it correctly but before going into detail I will mention important statement about host network.
The host networking driver only works on Linux hosts, and is not
supported on Docker for Mac, Docker for Windows, or Docker EE for
Windows Server.
https://docs.docker.com/network/network-tutorial-host/
Now in Linux, it's working as you expect.
Run nginx for testing
docker run --rm -it --network host --name my_nginx nginx:alpine
Goto your container...
docker exec -it my_nginx ash
If you cat /etc/hosts
You will all the host file inside the container is same as the host file of the Host Machine.
Now, run the other test image, just a public image from docker registry.
docker run --name="hello-world" -d -p 8080:8080 kornkitti/express-hello-world
If you do inside nginx container
apk add curl
curl localhost:8080
A hello world response from nodejs container.
For mysql It also working...
mysql -h localhost -u root -ptest
In case of window or Mac you can add the following.
docker run --rm -it --add-host=db.local.com:(host__ip_address) --name my_nginx nginx:alpine
And connect to mysql from containers like
mysql -h db.local.com -u root -ptest

Can't access MySQL database in Docker container from another container

I have MySQL 5.7 container pulled from here: https://hub.docker.com/_/mysql/
Here's how I run it:
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pwd -d mysql:5.7
It works good, I'm able to connect to MySQL db from my host machine.
However, when I try to run another container with mysql container linked like this:
docker run --link mysql:mysql -p 8080:8080 -d app:dev
my container can't connect to mysql:
# 172.17.0.3 is mysql's ip taken from /etc/hosts of another container.
mysql -h 172.17.0.3 -u root -ppwd
ERROR 2003 (HY000): Can't connect to MySQL server on '172.17.0.3'
I tried to use docker networks but I'm getting the same error.
Here's nmap -p 3306 172.17.0.2 output:
Starting Nmap 7.01 ( https://nmap.org ) at 2018-06-03 08:34 UTC
Nmap scan report for e66874413058 (172.17.0.2)
Host is up (0.00012s latency).
PORT STATE SERVICE
3306/tcp closed mysql
Nmap done: 1 IP address (1 host up) scanned in 0.39 seconds
For unknown reason, the port is closed. If I run nmap command from my host, it's open.
How to connect to MySQL server from another docker container?
I have to admit I don't see immediately where it's going wrong because also IP based communication should work but let me explain the recommended way to let containers communicate.
When you link your app container with the mysql container (like your doing) you can access the mysql just on it's container name without using ip's.
In the default bridge network:
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pwd -d mysql:5.7
Now I start a random app and link it with mysql. curl and ping are installed in this container.
docker run -d -p 8080:8080 --link mysql:mysql randomapp
Now I go inside my randomapp container and try to ping the mysql container which works.
docker exec -it 7c4bc6f1ca7a bash
xxx#7c4bc6f1ca7a:/$ ping mysql
PING mysql (172.17.0.3) 56(84) bytes of data.
64 bytes from mysql (172.17.0.3): icmp_seq=1 ttl=64 time=0.076 ms
64 bytes from mysql (172.17.0.3): icmp_seq=2 ttl=64 time=0.049 ms
I can verify with an nmap container too
docker#default:~$ docker run --rm --link mysql:mysql uzyexe/nmap mysql 3306
Starting Nmap 7.60 ( https://nmap.org ) at 2018-06-06 05:54 GMT
setup_target: failed to determine route to 3306 (0.0.12.234)
Nmap scan report for mysql (172.17.0.3)
Host is up (0.000010s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
3306/tcp open mysql
MAC Address: 02:42:AC:11:00:03 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 1.65 seconds
docker#default:~$
If you deploy your app and mysql in the same user defined bridge network you don't need to define the --link option and your containers can talk with each other by using their container name.
docker network create my-bridge
docker run --name mysql --net my-bridge -p 3306:3306 -e MYSQL_ROOT_PASSWORD=pwd -d mysql:5.7
docker run -d -p 8080:8080 --net my-bridge randomapp
It's recommended to use user defined networks and not the 'deprecated' --link feature in the default bridge network.

Docker. Connect from one container to another container with mysql

I have a network:
docker network create -d bridge --subnet 172.25.0.0/16 container_network
I have one container with mysql running. Run command:
docker run -tid -p 3306:3306 --name container_mysql --network container_network container_mysql
And one container with code:
docker run -tid -v $(pwd):/code -p 5000:5000 --name container_code --network container_network container_code
I am trying to access mysql DB from my container with code, but nothing works:
mysql -h 172.17.0.1 -P 3306 -u root -p
mysql -h container_mysql -P 3306 -u root -p
mysql -h 127.0.0.1 -P 3306 -u root -p
mysql -h 0.0.0.0 -P 3306 -u root -p
First command gives me:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
Others:
ERROR 2003 (HY000): Can't connect to MySQL server on <host> (111)
Any ideas how to achieve the goal?
Edit 1
Dockerfile for Mysql container:
FROM ubuntu:16.04
RUN apt-get update
RUN echo "mysql-server mysql-server/root_password password 1234" | debconf-set-selections
RUN echo "mysql-server mysql-server/root_password_again password 1234" | debconf-set-selections
RUN apt-get install mysql-server -y
First of all, you should consider to use networks insted of link. First, link should be deprecated very soon. Second, when you put 2 container on the same network, docker add to the /etc/hosts of both containers a line for resolve the IP from container name. This is for allows you to access to a container with their name. In your case you can access to the mysql container from code container like this
mysql -h container_mysql
Look this link for more details about docker networking. This link for more info about docker-compose and networking.