Connecting to MySql database in Docker - mysql

I'm trying to bring up 2 docker containers
app container - asp.net core api
db container - MySql database for
api
the api can't connect to the db. The docker-compose file is
services:
db:
image: mysql/mysql-server
container_name: db
ports:
- "49301:3306
environment:
MYSQL_ROOT_PASSWORD: Password1!
app:
image: mycontainner/api:1.0
container_name: app
build:
context: .
dockerfile: MyProject.Api\Dockerfile
ports:
- "49501:80"
environment:
- "ConnectionStrings:MySql=Server=db;Port=3306;Database=MyDb;Uid=root;Pwd=Password1!;SslMode=None;ConnectionReset=false;connect timeout=3600"
depends_on:
- db
networks:
default:
external: true
name: nat
I can ping between the 2 servers so the network is fine and they can see each other. I can browser to test api endpoints that don't connect to the database
The error says
An error occurred using the connection to database '' on server 'db'.
so the MySql host appears incorrect but for some reason it doesn't appear to pick up the database it's trying to connect to be it is specified in the connection string
If I launch a shell on the database then query the status of the MySql instance then I get
mysql Ver 8.0.26 for Linux on x86_64 (MySQL Community Server - GPL)
Connection id: 27
Current database:
Current user: root#localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 8.0.26 MySQL Community Server - GPL
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: latin1
Conn. characterset: latin1
UNIX socket: /var/lib/mysql/mysql.sock
Binary data as: Hexadecimal
So the server seems to be on localhost which looks right.
Anyone any ideas what I'm doing wrong?
The containers are windows but if I try linux containers then I still can't connect (the docker-compose file is slightly different but the network is still available)
Also - the database isn't actually there but entity framework migrations should create it on start up. I've also put up a temporary API endpoint which also runs the migrations put if I run that after all the containers are up then I still get connection errors. It all works fine outside of containers
Many Thanks

Related

How to connect to mysql docker container on a remote host from mysql workbench?

I've set up a docker container running a mysql instance on a remote computer I have. In the past this hasn't been an issue but for some reason I can't get it to work now. I am unsure what the issue might be. I am using docker compose and I can't seem to connect through mysql work bench on a different computer even those the container is running. Here are my details:
docker-compose.yaml
version: '3.7'
services:
api:
image: api
restart: unless-stopped
container_name: api
build: ./node/
ports:
- 3008:3008
mysql:
image: mysql
restart: unless-stopped
container_name: mysql
environment:
MYSQL_DATABASE: pitapaldb
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
build: ./database/
ports:
- 3306:3306
networks:
default:
external:
name: my-net
database/Dockerfile
FROM mysql
COPY init.sql /docker-entrypoint-initdb.d
database/init.sql
CREATE DATABASE mydb;
USE mydb;
SET SQL_SAFE_UPDATES = 0;
ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'password';
flush privileges;
CREATE TABLE carts (
id int PRIMARY KEY AUTO_INCREMENT,
lat float,
lon float,
address varchar(255),
status boolean,
city_id int
);
container is definitely running:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
784cf75183f4 mysql "docker-entrypoint.s…" 2 minutes ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
But when I try to connect via workbench I get 'unable to connect'. I've tried both username user and root with password password. The IP address I use definitely should work because I have other services operating from it with no issue:
#LoF10 Here is a quick list of things to check:
Can you connect within the docker network on the machine running the MySQL docker? An easy way of testing this is by running a command such as this on your remote machine:
docker run --rm -it --network my-net mysql:5.7 mysql -h mysql -uroot -ppassword
If not, there may be a problem with your MySQL config, MySQL data, or the initialization of the container. These are what #JorgeCampos is suggesting you verify. Since you are pulling directly from MySQL's Docker Hub entry, the config should be set properly to allow remote connections. If good, proceed. FYI, you will know you've connected successfully if you see mysql> on the terminal. To exit: \q.
Can you connect on exposed port on the localhost of the machine running the MySQL docker? An easy way of testing this is by running a command such as this on your remote machine:
docker run --rm -it --network host mysql:5.7 mysql -h 127.0.0.1 -uroot -ppassword
Make sure to use the IP used above and NOT localhost. This is b/c the MySQL client has special handling of the 'localhost' keyword by looking for mysqld locally. Using the 127.0.0.1 forces MySQL to connect via a proper socket connection. If you are not able to connect, then there is a problem with mapping the container's port to your host. If good, proceed.
Assuming both machines are on the same network and the machine that has MySQL Workbench also has docker, can you connect using the IP of the machine running MySQL container e.g. 10.0.0.4? An easy way of testing this is by running a command such as this on your remote machine:
docker run --rm -it mysql:5.7 mysql -h 10.0.0.4 -uroot -ppassword
If not, you may want to verify if you can:
Ping the 10.0.0.4 machine
If there are any firewall rules that prevent its proper exposure to the network. This happens commonly with Windows' default Firewall...
If on AWS, there are a number of reasons why you might not be able to reach if it has been properly assigned a Public Port e.g. Security Groups, Route Tables, Internet Gateway, etc.
Once you are able to proceed from 3 above, then you should be able to connect using MySQL Workbench as you've described.
Hope those help. Any more detailed recommendation will require you sharing more about your local networking setup (OS, Physical/Virtual, how you are determining IP's, etc).

Cirrus CI - Can't connect to MySQL additional container

I'm running a container on Cirrus CI, and in my .cirrus.yml, I've defined an additional_container to run a MySQL instance to test against as per the docs:
.cirrus.yml
container:
image: node:latest
additional_containers:
- name: mysql
image: mysql:8
port: 3306
cpu: 1.0
memory: 512Mi
env:
MYSQL_ROOT_PASSWORD: "pa55w0rd"
I'm trying to run a CREATE DATABASE command against that instance in one of my setup tasks:
...
mysql_setup_script:
- mysql -uroot -ppa55w0rd -P3306 -hlocalhost -e "CREATE DATABASE voluble_test;"
...
I've installed the MySQL client (but not the server, as this would defeat the object) on my testing container. However, MySQL acts as if it were connecting to a true localhost DB and looks for a locally-installed MySQL server, it appears - and fails with the following error:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")
That said, the Cirrus CI docs state that the MySQL instance should be available at localhost:
Tests will be able to access MySQL instance via localhost:3306.
I can't see an obvious way around this - any advice?
Using localhost will cause mysql not to use the network.
Use either 127.0.0.1 or your docker host IP, depending on network configs.
Notice that the error is not a network error:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
"through socket '/var/run/mysqld/mysqld.sock'", that file does not point to a mysql socket inside your docker container.
Grab your docker host IP with:
$ docker network inspect bridge --format='{{ (index .IPAM.Config 0).Gateway}}'

Docker nodejs with mysql communication

I'm using 2 docker images one with my nodeJS backend server the other with my MySQL database. On the docker-compose file I'm defining the passwords, ports and hostnames correctly:
sql:
image: mysql:5.7.22
hostname: sql
ports:
- 3306:3306
secrets:
- db_root_pass
- db_user_pass
environment:
MYSQL_USER: user
MYSQL_PASSWORD_FILE: /run/secrets/db_user_pass
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pass
provider:
image: monokilho/app:dev
hostname: provider
ports:
- 3000:3001
- 9221:9229
secrets:
- db_user_pass
command: node --inspect=0.0.0.0:9229 appModule.js
And on my DB_config.js file for NodeJS I have the connection setup like so:
db_config.host = 'sql';
db_config.port = '3306';
db_config.user = 'user';
db_config.password = fs.readFileSync('/run/secrets/db_user_pass', 'utf8');
db_config.database = 'app';
db_config.multipleStatements = true;
Problem is that although, using this exact configurations, docker connects Node to MySQL just fine on my local windows machine, when I upload the images to my remote linux server I continue to get:
Access denied for user 'user'#'8b2e56e566b2.network_default'
I've already remade the secrets, tried manually adding the passwords to the config on NodeJS and nothing... what makes it even weirder is that if I go on the MySQL container to connect directly or if I make another MySQL container and remotely connect it works, so I know the password input on MySQL config is correct and it is accepting remote connections.
Any suggestion what might be the difference between windows and linux for this behavior to happen? Thanks in advance.
PS: If needed windows is windows 10 and linux distro is ububtu 16.04.
EDIT: The access denied error appears on the mysql logs so the nodejs docker can reach the mysql docker and the network should be fine.
Apparently the mysql config was ignoring a sneaky \n on the password file allowing it to work normally with a command line connection, while on the nodejs it was bugging the connection.

Can't connect to mysql container from localhost

I'm trying to set up a MySQL container for developing.
So I used docker-compose to set it up.
The container and the mysql looks OK. The thing is that I want to connect to it from a DBeaver client and I can't find how I do it.
Here is my docker-compose.yml:
version: '2'
services:
db:
image: 'mysql:5.7'
volumes:
- '~/dev/dbs-data/mysql:/var/lib/mysql'
restart: 'always'
expose:
- '3306'
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: 'pass'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'pass'
When I try to connect it from DBeaver I get:
java.sql.SQLException: null, message from server:
"Host '172.18.0.1' is not allowed to connect to this MySQL server"
UPDATE
I'm not trying to connect using the IP 172.18.0.1. I tried to connect using localhost:3306, 127.0.0.1:3306 and with the sub IP docker gave it 0.0.0.0:3306
UPDATE
After having success connecting on my Mac, I tried again with DBeaver on my linux and again:
Tried to connect with other tool, mysql workbench:
As you can see in the official image documention :
MYSQL_ROOT_HOST : By default, MySQL creates the 'root'#'localhost' account. This account can only be connected to from inside the container, requiring the use of the docker exec command as noted under Connect to MySQL from the MySQL Command Line Client. To allow connections from other hosts, set this environment variable. As an example, the value "172.17.0.1", which is the default Docker gateway IP, will allow connections from the Docker host machine.
So you have to set the MYSQL_ROOT_HOST variable with the address 172.18.0.1 that you can see in the error message.
On Docker, run this command to create a MySql container and it will expose the ports to the outside world of docker.
docker run --name <mysql-container-name> -p 3306:3306 -e MYSQL_ROOT_PASSWORD=<root-password> -e MYSQL_USER=root -e MYSQL_PASSWORD=<user-password> -d mysql:latest
Few points to note:
You may see below error when trying to connect with DBeaver:
Public Key Retrieval is not allowed
Solution: When creating a new connection on DBeaver, go to Driver Properties look for allowPublicKeyRetrievel and set it to TRUE. Also, if needed set useSSL to FALSE.
Test your connection from DBeaver or any other clients, and it should be working.
I am new to docker and was experiencing the same issue in Linux, it was an issue with the addresses allowed to accept connection; here is what worked out for me:
Find the MySql configuration file named mysqld.cnf
It would be: /etc/mysql/mysql.conf.d/mysqld.cnfOr if you have your own configuration file.
Edit the bind-address key in it. Set it as: bind-address = 0.0.0.0
This will allow to accept connections from any IP address Restart docker-compose by $ docker-compose down$ docker-compose up
Wait for MySQL to start, it should work fine now.

Can't start application within docker using linked mysql database

I'm using docker to run my nodejs app with few databases, and one of them is mysql.
I found mysql image on the docker hub and use it in my docker-compose.yml
app:
build: .
volumes:
- ./:/var/www/app/
working_dir: /var/www/app/
command: node app.js
ports:
- "3000:3000"
links:
- mongo
- elasticsearch
- mysql
mysql:
image: mysql
environment:
MYSQL_DATABASE: testdb
mongo:
image: mongo
elasticsearch:
image: elasticsearch
Everything builds and application uses mysql conenction config that seems like this:
mysql: {
host: 'localhost',
user: 'root',
password: '',
database: 'testdb'
}
Application trying to start and stops on the the mysql connection error.
Error: connect ECONNREFUSED 127.0.0.1:3306
I'm wondering if docker mysql image could be linked to the app container via compose file. Please explain how to link mysql container properly.
Thanks in advance!
My own answer
When you're using any type of linking other containers(external_link or link) you may set in your application config file the process environment variables according to the name of the container
process.env.<container_name>_PORT_<container_port>
SailsJS to Mongo Example:
I have a container with name mongo_dev which is connected in my docker compose file as
external_links:
- mongo_dev
so in my application config this environment variable used like this:
mongo: {
module : 'sails-mongo',
host : process.env.MONGO_DEV_PORT_27017_TCP_ADDR || 'localhost',
port : process.env.MONGO_DEV_PORT_27017_TCP_PORT || '27017',
user : null,
password : null,
database : 'database_name'
}
The linked mysql container will be your mysql host
mysql: { host: 'mysql', user: 'root', password: '', database: 'testdb' }
You will see all you linked hosts are named in /etc/hosts like:
172.17.0.2 composetest_mysql_1 fffb39e63df6
172.17.0.2 mysql fffb39e63df6 composetest_mysql_1
172.17.0.2 mysql_1 fffb39e63df6 composetest_mysql_1
Use Connection String as Follows:
mysql://username:password#mysql:3306/demo