Win 10
Composer version 1.4.1 2017-03-10 09:29:45
PHP 7
npm/Node
Docker CE
Apache 2.4
Powershell
git BASH shell
drush (installed via composer)
Noob Composer/Docker skills
I have a docker config yml specifying how mysql service can start:
version: "2"
services:
mysql:
image: mysql:5.6
ports:
- 3306:3306
volumes:
- /data/nbif_mysql:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
And when I call
#!/bin/bash
docker-compose up -d mysql
I see that the container is running:
PS C:\dev\appname> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1a0ecab8af6 mysql:5.6 "docker-entrypoint..." 2 hours ago Up 5 seconds 0.0.0.0:3306->3306/tcp appname_mysql_1
But, notice that the reported IP is 0.0.0.0:3306->3306/tcp
So when I try to connect with the expected IP, it fails:
ERROR 2003 (HY000): Can't connect to MySQL server on '172.17.0.1' (10060)
How to I tell docker-compose to use that expected IP for docker?
Is this a setup issue, or some config tweak I need to do?
When you bind a port to your host, you have to use localhost instead of the container's IP address, because you're not assigning any local IP address.
Every container always runs in a isolated network (bridge), the container in your compose file will be able to find the others by their hostname, but inside of those containers, they are isolated from the local network so that's why you can't reach them.
In your compose file you only have a mysql container and you're binding that port in your host, so the only way to reach that container is by using localhost:3306
Remember, when you run a docker container it isn't like a server with an IP in your host network, it's more like a virtual machine with an isolated network configuration.
Take a look on the docker-compose docs in this specific topic:
https://docs.docker.com/compose/networking
UPDATE:
The link that finally answered the question was:
https://docs.docker.com/engine/userguide/networking/default_network/custom-docker0/
Related
In company we migrating some applications to Docker Container but apps has been connected to MySQL databse.
task which I stuck is the application is running on Docker and also the MySQL database which used by app I dockerized from officle image. But problem is the database is empty. i need to connect to already existing DB which is seperate server or migrate Data to newly created conternized Image. So I don't know which is best way and how to connect already exisitng db to dockerized app
I wanna ask what is the best way?
a) Dockerize MySQL from official image and migrate all data from host.(but data is very big to migrate) b) Connect App to the already existing database which is outside Docker container. c) Or any other way?
I tried to connect database which is outside Docker but not successfully
docker run -d --network=host \
-e "DB_DBNAME=database-1" \
-e "DB_PORT=3306" \
-e "DB_USER=admin" \
-e "MYSQL_ROOT_PASSWORD=pass" \
-e "DB_PASS=4815162342" \
-e "DB_HOST=database-1.amazonaws.com" \
--name somemysql2 mysql:latest
Any idea how to connect Docker app to the database which on another server and not in Docker container?
Thanks in advance for your help and support.
You have MySQL running in a Docker Container on a Host.
Different scenario's to connect to that MySQL Database:
From an App in another Container started in the same docker-compose.yml
If you started an App in the same docker-compose.yml and want to connect to the MySQL Database:
Use the Service as the Hostname because docker-compose has its own network and will translate the servicename to to right container
version: '3.9'
services:
mydb:
image: mysql:latest
volumes:
- "./.mysql-data/db:/var/lib/mysql"
restart: always
environment:
MYSQL_DATABASE: mysqldb
MYSQL_USER: root
MYSQL_PASSWORD: root
myapp:
....
In myapp you connect to MySQL with mysql://mydb:3306/....
No Ports section!! This is because MySQL itself publishes port 3306, so no Ports section needed in docker-compose.
From an App in another Container started in another Docker command
Suppose your App is started on the same Host but in another Docker command (or in another docker-compose.yml file)
Then you need to access the database via the Host published port. But there's a problem since you cannot access the host from within a Docker Container. (At least not in a stable way, so I leave out the hacky solutions you see here on StackOverflow)
Just create a (sub)domain and point it to your Host.
And make small change in your docker-compose.yml file: Add a Ports section:
ports:
- 3333:3306
The database can be found on mysql://subdomain:3333/.....
From an App running somewhere else on another Host.
This is the same as the previous solution:
Create subdomain
Publish the port
Connect to that subdomain
From Docker Container on Host to MySQL on another Server (not in Docker)
Again, same as before
Create subdomain
Publish the port on the Host
Connect to that subdomain
Solution with the subdomain need a ProxyServer?
In case your host also answers other requests from outside, you might need a ProxyServer (Nginx?) to route the 3333 traffic to port 3306 in the container.
And if you do have that ProxyServer, you don't need the Ports section anymore.
Answer to the question in the Problem Description
You want to connect to a MySQL database running on some AWS host.
That database is already running. It has a host, username, password.
Why are you starting a new Docker Container with MySQL Image?
Only thing you should start is that 'sampleapp' container with software connecting to the external MySQL.
I don't understand why you start a MySQL Container again if you already have an external one running on AWS.
I have a war file that uses the MySQL database in the backend.
I have deployed my war file in a docker container and I am able to ping this from my browser.
I want to connect my app with the MySQL database. This database exists on my host machine's localhost:3306
As I am unable to connect this from inside container's localhost, what I tried is,
I run a command docker inspect --format '{{ .NetworkSettings.IPAddress }}' 213be777a837
This command gave me an IP address 172.17.0.2. I went to MySQL server options and put this IP address in the bind field and restarted the server. After that, I have updated my projects database connection string with 172.17.0.2:3306
But it is not working. Could anyone please tell what I am missing?
I have also tried adding a new DB user with root#% and then run command allow all permission to 'root#%' but nothing worked.
Follow the steps:-
docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 dockernet
docker run -p 8082:8080 --network dockernet -d 6ab907c973d2
in your project set connection string : jdbc:mysql://host.docker.internal:3306/....
And then deploy.
tl;dr: Use 172.17.0.1:3306 if you're on Linux.
Longer description:
As I understand what you need to do is to connect from your Docker container to a host port. But what you have done is to try to bind the host process (MySQL) to the container networking interface. Not sure what the implications of a host process trying to bind to another host process network namespace, but IIUC your MySQL process should not be able to bind to that address.
When you start MySQL with default settings that bind it to 0.0.0.0 it's available for Docker containers through the Docker virtual bridge. Therefore, what you should do is to route your requests from the WAR process to the host process through that virtual bridge (if this is the networking mode you're using. If you have not changed any Docker networking settings, it should be). This is done by specifying the bridge gateway address as the MySQL address and the port it's started with.
You can get the bridge IP address by checking your network interfaces. When Docker is installed, it configures the virtual bridge by default, and that should show up as docker0 if you're on Linux. The IP address for this will most probably be 172.17.0.1. So your MySQL address from the container's point of view is jdbc:mysql://172.17.0.1:3306/....
1 - https://docs.docker.com/network/
2 - https://docs.docker.com/network/bridge/
From your question, I am assuming you both your war file and MySQL is deployed locally, and you want to connect them. One way to allow both containers that are locally deployed to talk to each other is by:
Create your own network docker network create <network-name>
Then when you run your war file and MySQL, deploy both of them using the --network. E.g.
War File: docker run --name war-file --network <network-name> <war file image>
MySQL: docker run --name mysql --network <network-name> <MySQL image>
After that, if you should be able to connect to your MySQL using mysql:3306 from inside your war file docker container, since they are both on the same custom network.
If you want to read up more about this, can take a look at docker documentation on network. (https://docs.docker.com/network/bridge/).
Your setup is fine. You just need to do this one change.
While running the application container (the one in which you are deploying your war file), you need to add following argument in its docker run command.
--net=host
Example:
docker run -itd -p 8082:8080 --net=host --name myapp myimage
With this change, you need not to change connection string as well. localhost:3306 would work fine. And you will be able to set up a connection with MySQL.
My new responsibility is porting our project into dockers. This means local code on each developer machine with test data on a staging server. At the moment, the code lives on the same server and thus uses local host (127.0.0.1) to connect to the database. The docker currently deploys and can run unit tests, which succeed in cases where no DB is required.
I've tried using the answers provided here: https://github.com/phpmyadmin/docker/issues/99
which failed at the time and with a variety of different attempts eventually led to trying to create SSH tunnels from inside the container (How do I complete this SSH tunnel from local development docker to staging database) . I've returned to trying to use the service, as the other options seem to be even more complicated or unreliable.
I've returned to using the kingsquare image that allows tunnelling but I don't know what ${SSH_AUTH_SOCK} is or how to use it. I've tried pointing it at an SSH key but that (probably obviously) fails.
I've included the whole docker-compose.yml, as an earlier mistake that I had not noticed is not including network reference in my existing docker (app) .
version: '3'
services:
tunnels:
image: kingsquare/tunnel
volumes:
- '${SSH_AUTH_SOCK}:/ssh-agent'
command: '*:3306:localhost:3306 -vvv user#[myserver->the IP of the machine hosting the DB?] -i /.ssh/openssh_ironman_justin -p 2302'
networks:
mynetwork:
aliases:
- remoteserver
app:
build:
context: .
dockerfile: .docker/Dockerfile
args:
APP_PATH: ${APP_PATH}
image: laravel-docker
env_file: .env
ports:
- 8080:80
# We need to expose 443 port for SSL certification.
- "443:443"
volumes:
- .:/var/www/jumbledown
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
In the .env file, every developer has the following, which I need to change once the SSH tunnel is completed so that it uses the tunnel-DB combination:
DB_HOST=127.0.0.1 # As per answer, this will change to the IP address of the server containing the database. I'll leave the current localhost reference rather than displaying the IP address of the machine.
DB_PORT=3306
DB_DATABASE=[central database or sharded version for testing data changes]
DB_USERNAME=[username]
DB_PASSWORD=[password]
I'd like to be be able to get the code in the app container able to use the database on the remote server, with as little post-deployment complication as possible.
Update
I resolved a port issue.
Update 2.5
if I use
command: '*:3306:localhost:3306 -vvv [username]#[IP of DB host] -i [location on my PC of key file]/openssh_dev -p 2302'
then it does establish a connection but it gets turned down with:
tunnels_1 | debug1: Trying private key: /.ssh/openssh_ironman_justin
tunnels_1 | ###########################################################
tunnels_1 | # WARNING: UNPROTECTED PRIVATE KEY FILE! #
tunnels_1 | ###########################################################
tunnels_1 | Permissions 0755 for '/.ssh/openssh_dev ' are too open.
tunnels_1 | It is required that your private key files are NOT accessible by others.
tunnels_1 | This private key will be ignored.
But how do I change the permissions of a mounted file? Can it be done via Dockerfile, or must it already be present before that starts?
But how do I change the permissions of a mounted file? Can it be done
via Dockerfile, or must it already be present before that starts?
The Dockerfile is used to create the image. The container based on that image mounts the directory from your host machine and maintains the same host permissions.
You can change the permissions of the file on your host, Docker will use the same permissions in the container.
For your docker container 127.0.0.1 is its localhost. To access the host machine you need to change the host to 0.0.0.0. On the other hand, if you want to connect to a remote host then it'll be your-host-ip-or-domain.com.
I am working with PhpStorm 2018.3.4, Docker, MySQL and Ubuntu.
I tried unsuccessfully to configure MySQL with the Docker container network_mysql.
First, I have tried this configuration :
It gave me this error :
Then, I tried this :
This one gave me this other error.
Am I missing something? Is there another place where I must configure something?
docker ps output :
Here docker network ls :
For the command docker inspect network_mysql, here is a link to the description :
https://pastebin.com/9LmeAkc8
Here is a docker-compose.yml configuration :
https://pastebin.com/DB4Eye4y
I tried to put - "3306:3306" in addition to the wex_server_proxy section with no avail.
The file to modify was this one :
https://pastebin.com/TPBQNCDZ
I added the ports section, opening the 3306 port :) And then, it works.
Solution
I notice that you are not mapping the mysql container port out. If you did, you would see this from the docker ps command:
... 0.0.0.0:3306->3306/tcp network_mysql
The container network_mysql is attached to a bridge type network called tmp_wex_net. This means that the container is not accesible from the host, by it's container name.
I appears that you are using a docker-compose.yml definition for the stack. In order to be able to access the container from the host, you need to use the ports section of your compose definition for this container:
serivces:
mysql:
...
ports:
- "3306:3306"
...
If you are starting it with docker run, then you can acomplish the same thing with:
docker run -p 3306:3306 --name network_mysql --network="tmp_wex_net" -d mysql
And then use localhost in the hostname of your connection settings in PHPStorm. Like this:
Host: localhost
Port: 3306
Database: network
The problem
The reason that you are not able to connect, is that the host name network_mysql that you specify in the connection settings, does not resolve to any host that your machines knows of.
The container name of a docker container, is not a DNS name that the docker host can resolve.
If you have not specified any network for your mysql container, then it is connected to the default bridge network. And if you have created a new network, without specifying the type - it will also default to the bridge driver.
In order to access the container from the host, you need to either:
Connect the container to the host network
Or from a container on a bridge network, map the port to the host like suggested in the solution above. You can then address the specifically mapped port on that container with localhost:<portnum> from the host machine.
For everyone who has setup mysql manually in a docker image:
chances are you must configure mysql to accept incoming connections also from the network interface which docker creates/uses to communicate with the host (along with port forwarding).
in my case, i added the following to /etc/mysql/my.cnf to the end of the file:
[mysqld]
bind-address = 0.0.0.0
With that mysql listens on all network interfaces.
My solution:
I forwarded ports from localhost to remote: ssh -R 3306:localhost:3306 root#remote_host_ip and the connection was successful.
I am trying to setup a compose file to support a legacy application. Said legacy app needs to connect to up to 3 DBs (MySQL). The problem is I can't change the port specification. I mean, I probably could, but we want to containerize everything without having to change any code.
when I run docker inspect on one of my containers I get:
"IPAddress": "172.18.0.2",
which is good. But when I attempt to connect from my MAC
I get timeout. In the past, I have had to make a network alias like such:
sudo ifconfig lo0 alias 10.200.10.1/24
But, it doesn't seem to help
$ docker -v
Docker version 17.06.2-ce, build cec0b72
mac:
$ uname -a
Darwin wa-cbongiorno-mba.local 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
Here is the compose file I am working with:
version: '3.3'
services:
db1:
image: mysql:5.6
ports:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
volumes:
- ./Schema/db1:/docker-entrypoint-initdb.d/:ro
db2:
image: mysql:5.6
ports:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
volumes:
- ./Schema/db2:/docker-entrypoint-initdb.d/:ro
If you read the documentation, this is not possible as of now on mac
Known Limitations, Use Cases, and Workarounds
Following is a summary of current limitations on the Docker for Mac networking stack, along with some ideas for workarounds.
There is no docker0 bridge on macOS
Because of the way networking is implemented in Docker for Mac, you cannot see a docker0 interface in macOS. This interface is actually within HyperKit.
I cannot ping my containers
Unfortunately, due to limitations in macOS, we’re unable to route traffic to containers, and from containers back to the host.
Per-container IP addressing is not possible
The docker (Linux) bridge network is not reachable from the macOS host.
Use cases and workarounds
There are two scenarios that the above limitations will affect:
I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST
The Mac has a changing IP address (or none if you have no network access). From 17.06 onwards our recommendation is to connect to the special Mac-only DNS name docker.for.mac.localhost which will resolve to the internal IP address used by the host.
I WANT TO CONNECT TO A CONTAINER FROM THE MAC
Port forwarding works for localhost; --publish, -p, or -P all work. Ports exposed from Linux are forwarded to the Mac.
Our current recommendation is to publish a port, or to connect from another container. Note that this is what you have to do even on Linux if the container is on an overlay network, not a bridge network, as these are not routed.