How to connect to a MySQL Docker Container via SSH? - mysql

When I try to tunnel via SSH to the Host Mashine (vServer) and then try to connect via the internal docker Container-IP then I can't connect to MySQL.
This is my docker-compose file.
version: '2'
services:
mysql:
build: ./mysql
environment:
MYSQL_ROOT_PASSWORD: test
volumes:
- ./db:/var/lib/mysql
The only solution I found was to forward the MySQL-Port of the mysql container to the Host-Mashine.
version: '2'
services:
mysql:
build: ./mysql
environment:
MYSQL_ROOT_PASSWORD: test
volumes:
- ./db:/var/lib/mysql
ports:
- 3306:3306
Then I am able to connect via the Host IP to MySQL but this is without SSH its direct via TCP and the port.
This is a No-Go for me to bring the MySQL Service into the internet.
Reasons can be found here https://security.stackexchange.com/questions/63881/is-it-not-safe-to-open-mysqls-port-to-the-internet why it is not a good practice to bring your mysql port into the internet.
So what is a good practice to connect to my docker mysql container with SSH but keep the mysql ports closed?

One simple way is to bind the MySQL port only to the localhost address. That assumes the host has a mysql client available outside of Docker.
ports:
- 127.0.0.1:3306:3306
You could also omit the ports section completely (no port binding at all), and use the mysql client that's already inside the container.
docker-compose exec mysql bash
Then run the mysql command inside the container to do whatever queries you want to do.

An easy way to achieve this is to forward the ssh port of the docker conatiner to some port on your host, i.e.
ports:
- 22:<some free host port>
and then access the container via ssh to the host port you used. Note, that it is a bad idea to use port 22, since that will cause a conflict with the ssh server running on your host.

Related

How to connect local mysql(or docker container mysql) from docker container grafana?

I created grafana with a docker container. And I created mysql with docker container. After that, I tried to access grafana and add mysql container via 'data source'. However, the following error occurred. What is the problem?
db query error: query failed - please inspect Grafana server log for details
[grafana's data sources setting]
Host : 10.0.7.35:3306
And I set bind-address at '/etc/mysql/my.cnf' for 0.0.0.0:3306 in mysql container.
You can do it in three ways
You can run docker with MySQL and expose 3306 (by adding -p 3306:3306 port and find IP of docker and connect to that port on that IP from the same network
Expose MySQL port and then run app docker with --link name_of_mysql_container:mysql and then on the app docker just connect to name_of_mysql_container
Use Docker composer create
docker-composer.yml with content similar to:
version: '3.2'
services:
app:
build: .
image: lap
environment:
- DB_HOST=mysql
mysql:
image: mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
And then you can use in your app container database connection to host named 'mysql'

Access locally mysql on docker from remote through SSH tunnel

I'm trying to access my mysql database from workbench through SSH tunnel, mysql is in a container (working with docker-compose).
Here is my mysql container config in docker-compose :
mysql:
image: mysql:5.7
container_name: mysql
expose:
- 3306
ports:
- '3306:3306'
volumes:
- ./mysql:/var/lib/mysql
environment:
- "MYSQL_ROOT_PASSWORD=#####"
- "MYSQL_DATABASE=#####"
- "MYSQL_USER=#####"
- "MYSQL_PASSWORD=#####"
restart: always
But I'm getting a "Failed to Connect to MySQL" error, just like if my ports were not well reforwarding from SSH to MySQL container (and so, not hitting the good door).
Please note I did not allowed remote access from mysql, as I want to only keep SSH/localhost access possible.
Do you have any idea? Thanks
You are already exposing port 3306, so you should be able to access it from your system with below command -
mysql -u <mysql_user> -p -h localhost -p 3306
If not accessible, try if you are able to access it inside the docker session by logging in to mysql container in interactive mode.

I can't connect to mysql in docker from my localhost with DataGrip database client

I have the following docker-compose.yml file:
version: '3.2'
services:
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=verysecret
- MYSQL_DATABASE=yii2advanced
- MYSQL_USER=yii2advanced
- MYSQL_PASSWORD=secret
I run it via docker-compose up -d. But I can't connect from SQL client to my database (I use DataGrip from JetBrains). Here is my configuration:
The password of course is secret. I have already tried to check allowed hosts for yii2advanced user:
As you can see for my yii2advanced connection is allowed from any host. I have tried to change mysqld.cnf and set bind-address = 0.0.0.0. Tried to setbind-address to *. Tried to set not 127.0.0.1 but 172.17.0.1 in the settings of my SQL client. Tried to create manually new one user with full privileges. No effect. The problem still exists. I can't connect to mysql in the container from my localhost.
What is wrong?
By default, docker-compose create a bridge network that will isolate your application from outside including the localhost.
You need to expose 3306 port from isolated network to localhost.
Try this.
version: '3.2'
services:
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=verysecret
- MYSQL_DATABASE=yii2advanced
- MYSQL_USER=yii2advanced
- MYSQL_PASSWORD=secret
ports:
- 3306:3306 # <host port>:<container port>
Good to read docker network section. https://docs.docker.com/network/

Connecting to MySql server running in a Docker Container

I have a little problem, I can't seem to connect to mysql server community edition running inside a docker container.
I can easily connect to mysql server using the cli by using:
docker exec -it mysqlserver mysql -uroot -p
But if I try to connect with any other database connector, like DataGrip or MySql Workbench, I get an access denied.
But I changed nothing in the configuration files. I set ip as localhost, using the default 3306 port that the container exposed. username I keep as root and the password is exactly the same but it still keeps failing.
Am I missing something, not understanding anything properly?
Some help would be greatly appreciated!
Extra info: I am using MacOS, running the container with Docker for Mac and I am using as of this moment the latest MySql database version.
your container doesn't contain other connectors, try to publish port when you run your container with docker run --name mysql -p 127.0.0.1:3306:3306 .... to link port. And you can connect you to the container with your local cli. Try this doc
Below is the docker-compose.yml that I used to start up a MariaDB instance for testing some queries. MariaDB is API-compatible with MySQL, so no difference.
version: "2"
services:
db:
image: bitnami/mariadb:latest
volumes:
- ./mariadb/data:/bitnami
ports:
- "9001:3306"
environment:
MARIADB_ROOT_PASSWORD: ChangeMeIfYouWant
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- "9010:80"
links:
- db:db
The image is downloaded and the container created and started via docker-compose up. Afterwards, I can easily connect to it using JetBrains DataGrip.
host: localhost
port: 9001
user: root
password: ChangeMeIfYouWant

Get database address with Docker

I use docker-compose with the following docker-compose.yml:
web_db:
image: mariadb:latest
restart: always
volumes:
- ./var/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: X
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: X
MYSQL_ROOT_PASSWORD: X
web_front:
image: nginx
restart: always
ports:
- 80:80
links:
- web_fpm
volumes:
- ./www:/var/www/html:rw
- ./etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
web_fpm:
build: ./PHP-FPM/
restart: always
links:
- web_db:mysql
volumes:
- ./www:/var/www/html
When configuring Wordpress (manually downloaded in nginx root directory), I'm asked for the address of the database. I've tried localhost, but it doesn't work.
PS: I know there are Wordpress images for Docker, but they have the full stack (nginx + PHP) and I don't like it, so don't propose them. ;)
Try 'web_db' instead of localhost
https://docs.docker.com/compose/compose-file/
Containers for the linked service will be reachable at a hostname identical to the alias, or the service name if no alias was specified.
You need to reference mysql because in your compose file you have linked your container to the web_db container and given it an alias of 'mysql'. The web_fpm container will have a record in it's hosts file for mysql which will point to the web_db container.
Alternatively, if you just want to get the ip to enter manually, just run docker inspect <web_db_container_id>
edit: You will want to put in the IP of the host machine along with port 3306 and here is why.
When starting a container with Docker it is started using an IP assigned from the Docker. These are all accessible to docker via the docker0 bridged network. Docker in turn makes those accessible to the host machine by bridging the docker0 NIC on the host machine with the host machines eth0/1 ect.
When you EXPOSE a port explicitly via docker run -td -p <some external port>:<some internal port> Docker opens that port up in the host IPTables so it is accessible on the local network. If you do not explicitly open the port but it is exposed in the container (the docker file will say EXPOSE 3306 for MySQL in its Dockerfile.) then the container is only available to the machine.
Now, when working with Docker containers it's important to know this because when you do a link with docker-compose you are only telling that container where another container is on the local docker network. This only helps if you have containers that start and are looking for a dependent container.
To summarize, when containers are started they are started with a Docker IP that is only used by Docker and bridged back to the host machine via docker0, and this is key. Docker isolates those IP and forces you to either open the ports on the machine to access via your local network.
Back to your question and why you need to pass it the host IP and port 3306.
You need to do this because you are making making a request on your network. If you put in localhost it will not work because the container is not really running on localhost it's running on some 172.17.42.x address so telling WordPress it's on localhost, it's not. It is however on at the host machines IP because the host machine is bridged to docker0. This is why you have to give it the host machines IP. Because you network can't resolve the 172.17 address since that is specific to Docker and specific to that machines containers. This is very fundamental to Docker networking and important to understand. See this article for more information.