Unable to connect to MySQL database in docker container - mysql

I'm honestly tired of this. I've tried every possible solution but it still refuses to connect.
Here is my docker-compose file:
version: '3'
services:
# Database
db:
image: mysql:5.7
container_name: db
restart: always
env_file: .env
environment:
- MYSQL_ROOT_HOST=%
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=$MYSQL_DATABASE
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
networks:
- backend
# Wordpress
wp:
depends_on:
- db
image: wordpress:php7.3-fpm
container_name: wordpress
restart: always
env_file: .env
environment:
- WORDPRESS_DB_HOST=db:3306
- WORDPRESS_DB_USER=$MYSQL_USER
- WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
- WORDPRESS_DB_NAME=$MYSQL_DATABASE
volumes:
- ./wordpress:/var/www/html
networks:
- backend
# Nginx
nginx:
depends_on:
- wp
image: nginx
restart: always
ports:
- "80:80"
volumes:
- ./wordpress:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
networks:
- backend
networks:
backend:
driver: bridge
I've tried 127.0.0.1, 0.0.0.0, db, docker inspect db to get ip address of the container. All of them fail to connect. I've used Sequel Pro, MySQL Workbench and DataGrip.
The setup works completely fine. Its just that I cant connect to the database outside the container.
I even checked the mysql host privileges in the container and got:
% root
% wordpress (name of the user I created)
...
Am I missing something?

In order to reach your database from the host machine with an sql client you need to map the MYSQL database port to the host machine.
In your Compose file add the port mapping to your db service.
db:
...
ports:
- "3306:3306"
I believe you are using the default port based on your Wordpress service.
Then configure your SQL client to 127.0.0.1 and port 3306.

MYSQL Changes
MY.ini changes in c:\programdata\mysql\mysql server 8.0
Add Bind_address=0.0.0.0
Save as Admin - Check timestam
Create one App user - Dont user mysql Root user for app
drop user 'username'#localhost;
FLUSH PRIVILEGES;
CREATE USER 'username'#'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'username'#'localhost' WITH GRANT OPTION;
CREATE USER 'username'#'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'username'#'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
Restart the MYSQL Server
Restart Docker for Windows
Check Hosts files in C:\Windows\System32\drivers\etc if host.docker.internal variable is updated correctly
# Added by Docker Desktop
10.0.0.6 host.docker.internal
10.0.0.6 gateway.docker.internal
Application Changes:
User host.docker.internal in JDBC URL in app.properties
spring.datasource.url=jdbc:mysql://host.docker.internal:3306/test
spring.datasource.username=username
spring.datasource.password=password
maven install should work
docker run <repo/repo>:image should work fine. now

Related

Cannot access Mysql DB as root using phpmyadmin

I have this docker-compose file:
version: "3"
services:
db:
image: mysql/mysql-server:5.7
container_name: mysqldb
restart: always
environment:
MYSQL_ROOT_PASSWORD: 4dfLtRah2C
MYSQL_DATABASE: db
MYSQL_PASSWORD: le562BplPk
MYSQL_USER: db_user
networks:
- backend
volumes:
- ./db_data:/var/lib/mysql
phpmyadmin:
container_name: phpmyadmin
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- '9006:80'
environment:
MYSQL_ROOT_PASSWORD: 4dfLtRah2C
PMA_PORT: 3306
PMA_HOST: db
networks:
- backend
networks:
backend:
When I try to use the db_user with the MYSQL_PASSWORD it works, but when I try to login as the root user and use the MYSQL_ROOT_PASSWORD it does not work, gives me a connection refused error.
I can login in to the db via the container using mysql -u root --password=$MYSQL_ROOT_PASSWORD and it works just fine...
Already tried to do docker system prune -f -a --volumes as well as removing the db_data folder multiple times to ensure that the container runs as a fresh instance.
How may I fix this? What is wrong?
The problem here was that phpmyadmin was trying to use root#localhost, but we want to use root#db, to fix this we simply need to perform a few modifications on the database, in order to change the host of the user root to %, like this:
(inside the db container: mysql -u root -p)
use mysql;
UPDATE mysql.user SET host='%' WHERE host='localhost' AND user='root';
FLUSH privileges;
exit;
Now I can use phpmyadmin to manage all the databases using root.
Please note that you should not abuse the root user use, instead try to use the dedicated user for your specific database, but as this is a development environment and everything is containerized no harm should come from using root.

Can't migrate existing MySQL Wordpress database to Docker with docker-compose

I'm trying to migrate a pre-existing Wordpress install from an exported SQL file to a local Docker development environment. I'm somewhat new to Docker, but I have gone through some tutorials and documentation. The problem appears to be that the "wordpress" and "phpmyadmin" services cannot access the database.
I did a search & replace in Vim on the SQL file to replace instances of the original URL with "http://localhost:8000". Then I used docker-compose.
# docker-compose.yml
version: "3.7"
services:
db:
image: mysql:5.7.29
volumes:
- ./dbdata-import/:/docker-entrypoint-initdb.d/ # Where my exported SQL file is stored
# I also tried -./dbdata-import/thedata.sql:/docker-entrypoint-initdb.d/thedata.sql
- ./dbdata:/var/lib/mysql # So local database changes persist
ports:
- "3306:3306"
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wp_database
MYSQL_USER: wp_username
MYSQL_PASSWORD: wp_password
wordpress:
depends_on:
- db
image: wordpress:php7.3-apache
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_username
WORDPRESS_DB_PASSWORD: wp_password
WORDPRESS_DB_NAME: wp_database
WORDPRESS_TABLE_PREFIX: wp_ #Tried without and without this
WORDPRESS_DEBUG: 1
volumes:
- ./wp-vol:/var/www/html
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin:4.9.4
container_name: phpmyadmin
environment:
PMA_HOST: db
PMA_USER: admin
PMA_PASSWORD: phpmyadmin_password
restart: always
ports:
- "8080:80"
It might be worth noting that I use this fix so I can still use OpenVPN. Basically, I created a subnet by running docker network create localdev --subnet 10.0.1.0/24. I also added this file next to my docker-compose.yml:
# docker-compose.override.yml
version: '3.7'
networks:
default:
external:
name: localdev
When I access http://localhost:8000, I don't get anything and the browser times out. When I access http://localhost:8080 for PHPMyAdmin, I get the error:
MySQL said: Documentation
Cannot connect: invalid settings.
mysqli_real_connect(): (HY000/1045): Access denied for user 'admin'#'10.0.1.3' (using password: YES)
phpMyAdmin tried to connect to the MySQL server, and the server rejected the connection. You should check the host, username and password in your configuration and make sure that they correspond to the information given by the administrator of the MySQL server.
It seems odd this would be a credential issue. I pulled the Wordpress database information straight from wp-config.php on the host server. I also tested the database, username and password by signing into the MySQL CLI on the host server.
I used docker-compose down -v to delete volumes after I finished and docker volumes ls appears to be empty. So I don't think this is an issue with /docker-entrypoint-initdb.d/ not running because MySQL already initalized. However, I'm not sure.
I've been troubleshooting this for awhile now. I've done an almost identical Docker setup without /docker-entrypoint-initdb.d to create fresh Wordpress installs. That works fine. I could really use some help. I'm currently running Debian 10. Thanks.
UPDATE: I'm still having issues. I verified that I still have the same issues when I shutdown OpenVPN, remove docker-compose.override.yml and remove the localdev network. I get all the same problems. The only difference is that PHPMyAdmin gives me a different IP address after "admin#", which is expected.
I logged into my MySQL container using docker exec -it. Running MySQL CLI with my username and password worked. The tables looked like all the data was imported by docker-entrypoint-initdb.d. So the issue doesn't appear to be with docker-entrypoint-initdb.d, but rather the wordpress and phpmyadmin services can't access the database.
UPDATE 2: I fixed MyPHPAdmin. I didn't realize that PMA_USER and PMA_PASSWORD need to match the Wordpress database. I also needed PMA_HOST to include the port number:
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin:4.9.4
environment:
PMA_HOST: db:3306
PMA_USER: wp_username
PMA_PASSWORD: wp_password
restart: always
ports:
- "8080:80"
I still need help with Wordpress.

mysqld: dial tcp 127.0.0.1:3306: connect: connection refused

I'm trying to dockerize monitoring of mysql using prom/mysqld-exporter and prom/prometheus. I have configured the docker-compose.yml file like the following:
version: '3'
services:
mysql:
image: mysql
container_name: mysql
restart: always
volumes:
- mysql:/var/lib/mysql
# command:
# - CREATE USER 'root'#'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3;
# - GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'root'#'localhost';
environment:
- MYSQL_ROOT_PASSWORD= password
- MYSQL_DATABASE= db #Defining a new Database
- MYSQL_USER= mostafa
- MYSQL_PASSWORD= ghadimi
ports:
- 3306:3306
- 33060:33060
prometheus:
image: prom/prometheus
container_name: prometheus
ports:
- 9090:9090
volumes:
- prometheus:/prometheus
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
command:
- --config.file=/etc/prometheus/prometheus.yml
mysql-exporter:
image: prom/mysqld-exporter
container_name: mysql-exporter
ports:
- 9104:9104
volumes:
- ./mysql-exporter/.my.cnf:/root/.my.cnf
depends_on:
- mysql
volumes:
mysql:
prometheus:
and here is my ./mysql-exporter/.my.cnf file:
[client]
user=mostafa
password=ghadimi
After running docker-compose up command, everything works properly except the following error!:
mysqld: dial tcp 127.0.0.1:3306: connect: connection refused
I don't know how can I fix it!
PS: I have also tried to connect to mysql through its container and docker exec -it <container-id> bash command and I have attempted all the possible passwords (like empty string and the password I have set in docker-compose file), but I face with another error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
Mysql-d exporter is looking for mysql instance on localhost, but it is not running on the localhost inside mysqld container. You will have to pass external connection string with the host of mysql because this is the name of mysql service in docker-compose. From mysqld-exporter docs - you will have to pass environment variable to mysqld-exporter container with this datasource connection string :
mysql-exporter:
image: prom/mysqld-exporter
container_name: mysql-exporter
ports:
- 9104:9104
volumes:
- ./mysql-exporter/.my.cnf:/root/.my.cnf
environment:
- DATA_SOURCE_NAME="user:password#mysql:3306/database"
depends_on:
- mysql
And change user, password and database name to your desired ones.

"Host '192.XXX.XXX.X' is not allowed to connect to this MySQL server" error when attempting to access mysql Docker container from another container

I have a docker compose file which creates one container to run my app (Ruby on Rails) and another to run a mysql server.
version: "3"
volumes:
test-db:
external: false
services:
db:
image: mysql:5.7
env_file: .env
environment:
MYSQL_DATABASE: test_development
MYSQL_ROOT_PASSWORD: foobar
MYSQL_USER: root
MYSQL_PASSWORD: foobar
volumes:
- test-db:/var/lib/mysql
ports:
- "3306:3306"
app:
build:
./
image: test_app:latest
env_file: .env
command: "rails server -b 0.0.0.0"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
tty: true
stdin_open: true
I exec into the db container, and can access the mysql cli as expected.
$ docker exec -it test_db_1 mysql -pfoobar
Welcome to the MySQL monitor. Commands end with ; or \g.
However, I am met with the following when I attempt to access the server through the app container.
$ docker exec -it test_app_1 mysql -hdb -pfoobar
ERROR 1130 (HY000): Host '192.168.144.3' is not allowed to connect to this MySQL server
Why is the container running the mysql server unable to receive requests from the test app container?
When I run docker ps, I see the following:
COMMAND PORTS
"rails server -b 0.0…" 0.0.0.0:3000->3000/tcp
"docker-entrypoint.s…" 0.0.0.0:3306->3306/tcp, 33060/tcp
By default when you start MySQL container, it creates automatically the root user which you are using it to access the same container test_db_1 based on environment variables passed, this root user is granted/allowed to connect from localhost only.
But if you want to access MySQL from the other container, you should create a user that is granted to connect to the database from a remote host (either username#% or username#container-name) - as each container has a different IP inside the docker default network,
Note: you can do that by logging into MySQL in the container, and create a user, in your case it will be something like: grant all on <your-database>#`%` to <yourusername>#`%` identified by '<password>'
portsoption expose the ports to your host machine but I don't think it does between the same between containers. Try using expose: 3306 on the db configuration. By the way, I'd like to point out that even though you are using depends_on option that doesn't guarantee your database will be up when you start your application only that the db container will be ready so keep that in mind.

How to connect locally hosted MySQL database with the docker container

Through docker-compose.yml I am able to run the application. Now we want to move the application to production, But we don't want to use the container database. So is there any way so that I can connect my local MySQL database with the application using docker-compose?
My docker-compose.yml looks like:
version: '3'
services:
web-app:
build:
context: .
dockerfile: web-app/Dockerfile
ports:
- 8080:8080
links:
- app-db
app-db:
build:
context: .
dockerfile: app-db/Dockerfile
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=Optimize
ports:
- 3306:3306
Instead of app-db part I just want to connect to my locally hosted mysql database.
Just use host.docker.internal instead of localhost.
To make it work on Linux, you just need to start your Docker container passing the parameter --add-host host.docker.internal:host-gateway
Find the host machine ip in the docker network. If you use docker-compose.yml version: "3" it's probably that that IP is: 172.18.0.1, but confirm it searching for the "Gateway" of your container (your host):
docker inspect <container-id-or-name> | grep Gateway
"Gateway": "",
"IPv6Gateway": "",
"Gateway": "172.18.0.1",
"IPv6Gateway": "",
So inside your docker application point to MySQL as this: 172.18.0.1:3306 (maybe in a configuration file). Take into account that that IP is fixed as long as the docker network still the same (the network is created by docker-compose, and it is not removed unless you do docker-compose down)
Also, check that your MySQL is listening to all of its interfaces. In your my.cnf search for bind-address that should be 0.0.0.0 (consider security issues if your server has public IP).
As an alternative you can bring to the container the same networking as your host, in order to share the localhost, so the container will find mysql there. Use network mode as "host":
version: '3'
services:
web-app:
build:
context: .
dockerfile: web-app/Dockerfile
ports:
- 8080:8080
network_mode: "host"
Then, point in your hibernate.properties to mysql as this: localhost:3306
Allow permission using mysqld.cnf
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 0.0.0.0
save your file and restart mysql server
sudo systemctl restart mysql.service
login to Mysql
mysql -h localhost -u root -p
GRANT ALL ON *.* TO 'root'#'localhost' IDENTIFIED BY 'yourpassword' WITH GRANT OPTION;
GRANT ALL ON *.* TO 'root'#'%' IDENTIFIED BY 'yourpassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
Find your IP
ip addr show
And use it in your docker container 192.168.x.x
If anybody is using mac os then please use docker.for.mac.host.internal instead of host.docker.internal as the environment variable.
Problem:
We had a same scenario where we wanted to setup a Development local machine setup for the services where a developer can just make docker-compose up -d and use all the latest dev builds in his local machine.
But we started facing issues while connecting our tomcat based web service configured as service in the docker-compose.yml to **mysql-8.0** service within the docker-compose. So as alternative and quick fix we thought to use local mysql configured on the local laptop with Ubuntu and docker-compose.
Our tomcat-application was using a application-dev.yml file with jdbc config variable to connect to the mysql, say something like
url: jdbc:mysql://db:3306/abcDB?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: abcderf
Docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
container_name: db
restart: unless-stopped
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=abcd
- MYSQL_PASSWORD=abcd
- MYSQL_DATABASE=abcdDB
volumes:
- ./sql-dump:/docker-entrypoint-initdb.d
command: '--default-authentication-plugin=mysql_native_password'
frontend:
container_name: frontend
image: abc/abc:frontend-1.1.36
depends_on:
- backend
nginx:
container_name: nginx
image: nginx:1.19-alpine
links:
- "frontend"
- "backend"
volumes:
- ./proxyConf:/etc/nginx/conf.d
ports:
- "80:80"
- "443:443"
backend:
container_name: backend
image: abc/abc:server-3.1.161
restart: unless-stopped
env_file: .env
environment:
- SPRING_PROFILES_ACTIVE=devtest
- DB_HOST=db:3306
- DB_NAME=abcDB
depends_on:
- db
Solution worked for us:
As we wanted to connect our docker-compose tomcat service from the local mysql we tried the below routes.
docker inspect <container-id-or-name> | grep Gateway which returned the ip Gateway ip value as`
"Gateway": "",
"IPv6Gateway": "",
"Gateway": "172.18.0.1",
"IPv6Gateway": ""
used the above Ip in the application-dev.yml as below ( URL post resolve of the ${DB_HOST} looks something as below But the IP changes to next highrt post the docker-compose down ex: 172.19.0.1)
url: jdbc:mysql://172.18.0.1:3306/abcDB?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: abcderf
Modified docker-compose.yml
version: '3'
services:
frontend:
container_name: frontend
image: abc/abc:frontend-1.1.36
depends_on:
- backend
nginx:
container_name: nginx
image: nginx:1.19-alpine
links:
- "frontend"
- "backend"
volumes:
- ./proxyConf:/etc/nginx/conf.d
ports:
- "80:80"
- "443:443"
backend:
container_name: backend
image: abc/abc:server-3.1.161
restart: unless-stopped
env_file: .env
environment:
- SPRING_PROFILES_ACTIVE=devtest
- DB_HOST=172.18.0.1:3306
- DB_NAME=abcDB
depends_on:
- db
and Also updated the bind-address = 0.0.0.0 in the /etc/mysql/mysql.conf.d/mysqld.cnf and from the mysql command line allow the root user to connect from any Ip.
Below were the only commands worked for mysql-8.0 as other were failing with error syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'abcd'' at line 1
GRANT ALL PRIVILEGES ON *.* TO 'root'#'localhost';
UPDATE mysql.user SET host='%' WHERE user='root';
Restart the mysql client
sudo service mysql restart
The easist way is use host.docker.internal instead localhost.
MONGO_SERVER = {
'host': 'host.docker.internal',
'port': 27017,
'username': 'admin',
'password': '123456'}
It works for me by adding network_mode in docker-compose.yml
version: '3'
services:
aservice:
image: image:latest
ports:
- "8080:8080"
- "8787:8787"
# Allow docker to connect to localhost
network_mode: "host"
locally I had MySQL running on port 3306 and MySQL container running on the same port 3306
You have to be sure that MySQL or whatever database service that you are using in your container is stopped in your local envirmint before connecting to it
In my case, I had MySQL running through Homebrew
brew services stop mysql