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
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.
I'm new to Docker and I can't seem to get my mariadb container running. I have just freshly installed Docker on Macbook Pro running High Sierra.
I've simple used this command:
docker run --name db -e MYSQL_ROOT_PASSWORD=test -d -p 3306:3306
mariadb
Which is supposed to create an image and run the container from it. But I get the following error:
docker: Error response from daemon: driver failed programming
external connectivity on endpoint db
(d4d6631ae53d644b5c28a803d5814a792c7af6925ebcf84b61b49b4a0fe30f4b):
Error starting userland proxy: Bind for 0.0.0.0:3306 failed: port is
already allocated.
So far I may have used MySQL in the far past, but I'm pretty sure I don't have anything running on port 3306.
I have also tried not adding the -p tag, it will run when I use this but when i execute docker ps it will show 3306/tcp and NOT 0.0.0.0:3306->3306/tcp as the PORT.
I have also tried just having to port tag as -p 3306 but this will show 0.0.0.0:32769->3306/tcp as the PORT in docker ps.
I would love some help. Thanks in advance.
Use lsof command to check if a service / process is using the port 3306.
$ lsof -i tcp:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 721 krisnik 34u IPv4 0x348c24a60c9d72a9 0t0 TCP localhost:mysql (LISTEN)
Now kill / stop the service.
kill -9 <PID>
Re-run your Docker container. It should work fine as the required port is released.
Edit - 1
If lsof doesn't catch the process, netstat can also be used.
sudo netstat -lpn |grep :3306
kill -9 PID //PID processID used by 3306 Port
Ref - Port 3306 busy but no process using it
I am running MariaDB and myqld_exporter both from docker. I run them like so :
docker run -p 127.0.0.1:3306:3306 --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -d mariadb
docker run -p 9104:9104 -e DATA_SOURCE_NAME="root:mypass#(127.0.0.1:3306)/" prom/mysqld-exporter
Replacing the 127.0.0.1 IP with localhost or my docker-machine ip default of 192.168.99.100 makes no difference either, as I always get the following output after executing the second command :
$ docker run -p 9104:9104 -e DATA_SOURCE_NAME="root:mypass#(127.0.0.1:3306)/" prom/mysqld-exporter
time="2017-10-17T12:26:57Z" level=info msg="Starting mysqld_exporter (version=0.10.0, branch=master, revision=80680068f15474f87847c8ee8f18a2939a26196a)" so
urce="mysqld_exporter.go:460"
time="2017-10-17T12:26:57Z" level=info msg="Build context (go=go1.8.1, user=root#3b0154cd9e8e, date=20170425-11:24:12)" source="mysqld_exporter.go:461"
time="2017-10-17T12:26:57Z" level=error msg="Error pinging mysqld: dial tcp 127.0.0.1:3306: getsockopt: connection refused" source="mysqld_exporter.go:268"
time="2017-10-17T12:26:57Z" level=info msg="Listening on :9104" source="mysqld_exporter.go:479"
My intention is to have Prometheus use the exporter metrics to monitor MariaDB
Should anyone find it useful, I figured out the commands that do work :
docker run -p 3306:3306 --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -d mariadb
docker run -p 9104:9104 -e DATA_SOURCE_NAME="root:mypass#(192.168.99.100:3306)/" prom/mysqld-exporter
it's a bit nicer to use links instead of ip adresses. You can start the exporter with docker run -p 9104:9104 --link mariadbtest -e DATA_SOURCE_NAME="root:mypass#(mariadbtest:3306)/" prom/mysqld-exporter. See https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#connect-with-the-linking-system
In a nutshell
I want to run mysql in a docker container and connect to it from my host. So far, the best I have achieved is:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
More details
I'm using the following Dockerfile:
FROM ubuntu:14.04.3
RUN apt-get update && apt-get install -y mysql-server
# Ensure we won't bind to localhost only
RUN grep -v bind-address /etc/mysql/my.cnf > temp.txt \
&& mv temp.txt /etc/mysql/my.cnf
# It doesn't seem needed since I'll use -p, but it can't hurt
EXPOSE 3306
CMD /etc/init.d/mysql start && tail -F /var/log/mysql.log
In the directory where there is this file, I can succesfully build the image and run it with:
> docker build -t my-image .
> docker run -d -p 12345:3306 my-image
When I attach to the image, it seems to work just fine:
# from the host
> docker exec -it <my_image_name> bash
#inside of the container now
$ mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
[...]
However I don't have that much success from the host:
> mysql -P 12345 -uroot
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
Even more details
I've seen that there's a question which looks like mine. However, it isn't the same (and it doesn't have any answers anyway)
I've seen that there are images dedicated to mysql, but I didn't have more success with them
My grep -v may feel weird. Admittedly, there may be cleaner way to do it. But when I attach my image, I can observe it actually worked as expected (ie: removed the bind-address). And I can see in the container /var/log/mysql/error.log:
Server hostname (bind-address): '0.0.0.0'; port: 3306
- '0.0.0.0' resolves to '0.0.0.0';
Server socket created on IP: '0.0.0.0'.
If your Docker MySQL host is running correctly you can connect to it from local machine, but you should specify host, port and protocol like this:
mysql -h localhost -P 3306 --protocol=tcp -u root
Change 3306 to port number you have forwarded from Docker container (in your case it will be 12345).
Because you are running MySQL inside Docker container, socket is not available and you need to connect through TCP. Setting "--protocol" in the mysql command will change that.
If you use "127.0.0.1" instead of localhost mysql will use tcp method and you should be able to connect container with:
mysql -h 127.0.0.1 -P 3306 -u root
I recommend checking out docker-compose. Here's how that would work:
Create a file named, docker-compose.yml that looks like this:
version: '2'
services:
mysql:
image: mariadb:10.1.19
ports:
- 8083:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: wp
Next, run:
$ docker-compose up
Notes:
For latest mariadb image tag see https://hub.docker.com/_/mariadb/
Now, you can access the mysql console thusly:
$ mysql -P 8083 --protocol=tcp -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.5.5-10.1.19-MariaDB-1~jessie mariadb.org binary distribution
Copyright (c) 2000, 2016, 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>
Notes:
You can pass the -d flag to run the mysql/mariadb container in detached/background mode.
The password is "wp" which is defined in the docker-compose.yml file.
Same advice as maniekq but full example with docker-compose.
The simple method is to share the mysql unix socket to host machine. Then connect through the socket
Steps:
Create shared folder for host machine eg: mkdir /host
Run docker container with volume mount option docker run -it -v /host:/shared <mysql image>.
Then change mysql configuration file /etc/my.cnf and change socket entry in the file to socket=/shared/mysql.sock
Restart MySQL service service mysql restart in docker
Finally Connect to MySQL servver from host through the socket mysql -u root --socket=/host/mysql.sock. If password use -p option
OK. I finally solved this problem. Here follows my solution used in https://sqlflow.org/sqlflow.
The Complete Solution
To make the demo self-contained, I moved all necessary code to https://github.com/wangkuiyi/mysql-server-in-docker.
The Key to the Solution
I don't use the official image on DockerHub.com https://hub.docker.com/r/mysql/mysql-server. Instead, I made my own by installing MySQL on Ubuntu 18.04. This approach gives me the chance to start mysqld and bind it to 0.0.0.0 (all IPs).
For details, please refer to these lines in my GitHub repo.
SQLFLOW_MYSQL_HOST=${SQLFLOW_MYSQL_HOST:-0.0.0.0}
echo "Start mysqld ..."
sed -i "s/.*bind-address.*/bind-address = ${SQLFLOW_MYSQL_HOST}/" \
/etc/mysql/mysql.conf.d/mysqld.cnf
service mysql start
To Verify My Solution
Git clone the aforementioned repo.
git clone https://github.com/wangkuiyi/mysql-server-in-docker
cd mysql-server-in-docker
Build the MySQL server Docker image
docker build -t mysql:yi .
Start MySQL server in a container
docker run --rm -d -p 23306:3306 mysql:yi
Install the MySQL client on the host, if not yet. I am running Ubuntu 18.04 on the host (my workstation), so I use apt-get.
sudo apt-get install -y mysql-client
Connect from the host to the MySQL server running in the container.
mysql --host 127.0.0.1 --port 23306 --user root -proot
Connect from Another Container on the Same Host
We can run MySQL client from even another container (on the same host).
docker run --rm -it --net=host mysql/mysql-server mysql \
-h 127.0.0.1 -P 13306 -u root -proot
Connect from Another Host
On my iMac, I install the MySQL client using Homebrew.
brew install mysql-client
export PATH="/usr/local/opt/mysql-client/bin:$PATH"
Then, I can access the above Ubuntu host (192.168.1.22).
mysql -h 192.168.1.22 -P 13306 -u root -proot
Connect from a Container Running on Another Host
I can even run MySQL client in a container running on the iMac to connect to the MySQL server in a container on my Ubuntu workstation.
docker run --rm -it --net=host mysql/mysql-server mysql \
-h 192.168.1.22 -P 13306 -u root -proot
A Special Case
In the case that we run MySQL client and server in separate containers running on the same host -- this could happen when we are setting up a CI, we don't need to build our own MySQL server Docker image. Instead, we can use the --net=container:mysql_server_container_name when we run the client container.
To start the server
docker run --rm -d --name mysql mysql/mysql-server
To start the client
docker run --rm -it --net=container:mysql mysql/mysql-server mysql \
-h 127.0.0.1 -P 3306 -u root -proot
if you running docker under docker-machine?
execute to get ip:
docker-machine ip <machine>
returns the ip for the machine and try connect mysql:
mysql -h<docker-machine-ip>
In your terminal run: docker exec -it container_name /bin/bash
Then: mysql
You should inspect the IP address assigned to the running container, and ther connect to that host:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container name or id>
than you can connect with:
mysql -h <IP provided by inspect command> -P <port> -u <user> -p <db name>
https://mariadb.com/kb/en/installing-and-using-mariadb-via-docker/#connecting-to-mariadb-from-outside-the-container
I do this by running a temporary docker container against my server so I don't have to worry about what is installed on my host. First, I define what I need (which you should modify for your purposes):
export MYSQL_SERVER_CONTAINER=mysql-db
export MYSQL_ROOT_PASSWORD=pswd
export DB_DOCKER_NETWORK=db-net
export MYSQL_PORT=6604
I always create a new docker network which any other containers will need:
docker network create --driver bridge $DB_DOCKER_NETWORK
Start a mySQL database server:
docker run --detach --name=$MYSQL_SERVER_CONTAINER --net=$DB_DOCKER_NETWORK --env="MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" -p ${MYSQL_PORT}:3306 mysql
Capture IP address of the new server container
export DBIP="$(docker inspect ${MYSQL_SERVER_CONTAINER} | grep -i 'ipaddress' | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])')"
Open a command line interface to the server:
docker run -it -v ${HOST_DATA}:/data --net=$DB_DOCKER_NETWORK --link ${MYSQL_SERVER_CONTAINER}:mysql --rm mysql sh -c "exec mysql -h${DBIP} -uroot -p"
This last container will remove itself when you exit the mySQL interface, while the server will continue running. You can also share a volume between the server and host to make it easier to import data or scripts. Hope this helps!
mysql -u root -P 4406 -h localhost --protocol=tcp -p
Remember to change the user, port and host so that it matches your configurations. The -p flag is required if your database user is configured with a password
docker run -e MYSQL_ROOT_PASSWORD=pass --name sql-db -p 3306:3306 mysql
docker exec -it sql-db bash
mysql -u root -p
For conversion,you can create ~/.my.cnf file in host:
[Mysql]
user=root
password=yourpass
host=127.0.0.1
port=3306
Then next time just run mysql for mysql client to open connection.
run following command to run container
docker run --name db_name -e MYSQL_ROOT_PASSWORD=PASS--publish 8306:3306 db_name
run this command to get mysql db in host machine
mysql -h 127.0.0.1 -P 8306 -uroot -pPASS
in your case it is
mysql -h 127.0.0.1 -P 12345 -uroot -pPASS
First, see the logs Are there any errors or not.
docker ps -a
docker logs container_name
If there is any error, search for the solution of that particular error, if there are no errors you may proceed to the next step.
Remember after starting your container MySQL take a few minutes to start so run those commands after 3-4 minutes.
docker exec -it container_name bash
# ONCE YOU ARE INSIDE CONTAINER
mysql -u root -p
SHOW DATABASES;
exit
To connect from terminal or command prompt
mysql -h localhost -P 3306 --protocol=tcp -u root -p
I have tried the same thing, and I was facing same problem, but I have noticed one thing, whenever I was trying to run docker container with /bin/bash like as below:
docker container run -it --name test_mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql:latest /bin/bash
After hitting the above command, my container getting start but facing the same error" ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)"
Now, I have tried instead of above command, I have used below command:
docker container run -itd --name test_mysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 mysql:latest
docker container exec test_mysql /bin/bash
then using the command
mysql -uroot -P3306 -p
then able to connect, Hope This idea will work in your case.
Thanks
Love Arora
I was able to connect mysql server 5.7 running on my host using the below command:
mysql -h 10.10.1.7 -P 3307 --protocol=tcp -u root -p
where the ip given is my host ip and 3307 is the port forwaded in mysql docker. After entering the command type the password for mysql. That is it. Now you are connected the mysql docker container from the your host machine.
According to the photos, go to the project -> MySQL -> inspect tab in the docker desktop app and modify the information about the database .env file.
.env file example:
DB_CONNECTION=mysql
DB_HOST=0.0.0.0:3306
DB_PORT=3306
DB_DATABASE=testdb
DB_USERNAME=sail
DB_PASSWORD=password
In case this will help somebody:
My prefered solution
add ~/.my.cnf with contents
[client]
user=<yourusername>
password=typethepasswordhere
host=127.0.0.1
port=3306
then from the terminal run >$ mysql and you should get in your sql cmd.
The hardcore alternative
you can also connect like this
docker exec -it containername mysql
To get into the sql cmd
or
docker exec -it contaiinername bash (or sh)
to connect in the container and then run >$ mysql
change "localhost" to your real con ip addr
because it's to mysql_connect()