Percona error reading communication packets with python - python

I have the same issue while trying to connect to mysql(percona) container upped with docker-compose.
I have this simple code
import sqlalchemy
engine = sqlalchemy.create_engine(
f'mysql+pymysql://root:admin#127.0.0.1:3306/DB_MYAPP',
encoding='utf8'
)
connection = engine.connect()
connection.close()
Here is the part of docker-compose.yml
mysql:
image: 'percona:latest'
container_name: 'mysql'
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: DB_MYAPP
MYSQL_USER: test_qa
MYSQL_PASSWORD: qa_test
ports:
- '3306:3306'
volumes:
- '/home/rolf/PycharmProject/Endshpiel/mysql/myapp_db:/docker-entrypoint-initdb.d'
Container is working
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f1556e66ccb percona:latest "/docker-entrypoint.…" 55 minutes ago Up 9 minutes 0.0.0.0:3306->3306/tcp mysql
Also i tried increasing max_allowed_packet
I can easily connect to docker container via linux terminal (host:127.0.0.1 port:3306) and work with database. But when i try to connect to container with python i get this error
mysql | 2022-05-24T23:17:10.428251Z 6 [Note] Aborted connection 6
to db: 'DB_MYAPP' user: 'root' host: '172.20.0.1' (Got an error
reading communication packets)

Related

(mysql.connector.errors.DatabaseError) 2005 (HY000): Unknown MySQL server host 'db' (8) (Background on this error at: https://sqlalche.me/e/20/4xp6)

I'm developing a project with Django and I want to use a database to create a dataframe, but I'm stuck with the subject issue (mysql.connector.errors.DatabaseError) 2005 (HY000): Unknown MySQL server host 'db' (8).
(Background on this error at: https://sqlalche.me/e/20/4xp6) How should I fix it?
views.py
from sqlalchemy import create_engine, text
def user_detail(req, id):
engine = create_engine("mysql+mysqlconnector://user:mariadb#db:9051/mariadb")
query = "SELECT * FROM LoanParcel"
df = pd.read_sql_query(sql=text(query), con=engine.connect())
df = df.drop(["id", "date_add", "start_date", "description"], axis = 1)
return render(req,'pages/user_detail.html')
docker-compose.yml
version: '3.7'
services:
db:
image: mariadb:10
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
- MYSQL_ROOT_PASSWORD=mariadb
- MYSQL_DATABASE=mariadb
- MYSQL_USER=mariadb
- MYSQL_PASSWORD=mariadb
- MARIADB_ROOT_PASSWORD=mysecretpassword
ports:
- 9051:3306
volumes:
- "mysqldata:/var/lib/mysql"
web:
build: .
restart: always
command: python manage.py runserver 0.0.0.0:8000
environment:
- DATABASE_URL=mysql+mysqlconnector://user:mariadb#db:9051/mariadb
ports:
- "9052:8000"
depends_on:
- db
volumes:
mysqldata:
docker-compose ps command
NAME COMMAND SERVICE STATUS PORTS
myproject-uborrowu-db-1 "docker-entrypoint.s…" db running 0.0.0.0:3306->3306/tcp
myproject-uborrowu-web-1 "python manage.py ru…" web running 0.0.0.0:8000->8000/tcp
You should add network attribute for yaml file. Containers must be run on same network like that https://docs.docker.com/compose/networking/
++ i found that
https://stackoverflow.com/a/71574076/17318894

Cannot connect to MySQL database container on Docker with Python script

When I try to connect to MySql Database my script get stuck. It simply does nothing. I use docker-compose.yml file (shown below) to run MySql database.
version: '3.1'
services:
db:
image: mysql
# NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password
# (this is just an example, not intended to be a production configuration)
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: database
adminer:
image: adminer
restart: always
ports:
- 3306:8080
My php script for database connection:
<?php
$conn = mysqli_connect('127.0.0.1', 'root', 'example', 'database');
if ($conn->connect_errno) {
echo("failed");
exit();
}
$conn->close();
?>
I have also created python script which also get stuck. Here is the code:
import mysql.connector
mydb = None
try:
mydb = mysql.connector.connect(
host="127.0.0.1",
user="root",
password="database",
use_pure=True
)
except Exception as e:
print(e)
print(mydb)
Log from docker-compose:
adminer_1 | [Thu Aug 11 22:03:52 2022] [::ffff:172.18.0.1]:56018 Accepted
For tests purposes I used php8.0-cli and python3.
Do you have any ideas what could be the reason?
You will either need to:
1: Expose the port on the database Docker container to allow access to it through your application
For example:
ports:
- "3306:3306"
2: Create a container for your application which can store your script in it, and you can tunnel into your mysql server via a virtual network.
For example:
networks:
default:
driver: bridge
And you can use this network on both of your application by adding the following under each app.
networks:
- default
Heres a good resource to kick you off. https://runnable.com/docker/docker-compose-networking

Can't connect python (Flask) with Mysql container using docker-compose [duplicate]

I am trying to run integration tests (in python) which depend on mysql. Currently they depend on SQL running locally, but I want them to depend on a MySQL running in docker.
Contents of Dockerfile:
FROM continuumio/anaconda3:4.3.1
WORKDIR /opt/workdir
ADD . /opt/workdir
RUN python setup.py install
Contents of Docker Compose:
version: '2'
services:
mysql:
image: mysql:5.6
container_name: test_mysql_container
environment:
- MYSQL_ROOT_PASSWORD=test
- MYSQL_DATABASE=My_Database
- MYSQL_USER=my_user
- MYSQL_PASSWORD=my_password
volumes:
- db_data:/var/lib/mysql
restart: always
expose:
- "3306"
my_common_package:
image: my_common_package
depends_on:
- mysql
restart: always
links:
- mysql
volumes:
db_data:
Now, I try to run the tests in my package using:
docker-compose run my_common_package python testsql.py
and I receive the error
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on
'localhost' ([Errno 99] Cannot assign requested address)")
docker-compose will by default create virtual network were all the containers/services in the compose file can reach each other by an IP address. By using links, depends_on or network aliases they can reach each other by host name. In your case the host name is the service name, but this can be overridden. (see: docs)
Your script in my_common_package container/service should then connect to mysql on port 3306 according to your setup. (not localhost on port 3306)
Also note that using expose is only necessary if the Dockerfile for the service don't have an EXPOSE statement. The standard mysql image already does this.
If you want to map a container port to localhost you need to use ports, but only do this if it's necessary.
services:
mysql:
image: mysql:5.6
container_name: test_mysql_container
environment:
- MYSQL_ROOT_PASSWORD=test
- MYSQL_DATABASE=My_Database
- MYSQL_USER=my_user
- MYSQL_PASSWORD=my_password
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
Here we are saying that port 3306 in the mysql container should be mapped to localhost on port 3306.
Now you can connect to mysql using localhost:3306 outside of docker. For example you can try to run your testsql.py locally (NOT in a container).
Container to container communication will always happen using the host name of each container. Think of containers as virtual machines.
You can even find the network docker-compose created using docker network list:
1b1a54630639 myproject_default bridge local
82498fd930bb bridge bridge local
.. then use docker network inspect <id> to look at the details.
Assigned IP addresses to containers can be pretty random, so the only viable way for container to container communication is using hostnames.

Docker expose ports between containers

I would like to have a python flask application that runs with a postgresql database (psycopg2). So I made this docker-compose file:
version: "3"
services:
web:
depends_on:
- database
container_name: web
build:
context: "."
dockerfile: "docker/Dockerfile.web"
ports:
- 5000:5000
volumes:
- database:/var/run/postgresql
database:
container_name: database
environment:
POSTGRES_PASSWORD: "password"
POSTGRES_USER: "user"
POSTGRES_DB: "products"
image: postgres
expose:
- 5432
volumes:
- database:/var/run/postgresql
volumes:
database:
In my app.py I try to connect to postgres like this:
conn = psycopg2.connect(database="products", user="user", password="password", host="database", port="5432")
When I run docker-compose up I get the following error:
"Is the server running on host "database" (172.21.0.2) and accepting TCP/IP connections on port 5432?"
I don't know where I have mistaken here.
The container "database" exposes its port 5432.
Both containers are on the same network which is "web_app_default".
The socket file existes in /var/run/postgresql directory on "web" container.
Any ideas ?
Thanks for replies and have a nice day.
I think what happened is that even though you have the flag depends_on set to database, that only means that the web container will start after database container starts. However, for the first time, the database will generally take quite some time to set up and when your web server is up, the database is still not ready to accept the connection.
2 ways to work around the problem here:
Easy way with no change in code: run docker-compose up -d (detach mode) and wait for the database to finish initializing. Then run docker-compose up -d again and your web container will now be able to connect to the database.
Second way is to update the web container with restart: always so docker-compose will keep trying to restart your web container until it runs successfully (until the database is ready to accept connection)
version: "3"
services:
web:
depends_on:
- database
...
restart: always
...

Is it possible to make a pymysql connection to a MySQL docker container?

I am having trouble making a connection to a MySQL container using pymysql from outside a container on Mac OSX, though I am able to connect to the docker MySQL with MySQL Workbench.
I used the following docker-compose.yaml:
version: '3'
services:
db:
image: mysql:latest
volumes:
- ./data/db:/var/lib/mysql
ports:
- 6603:3306
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: testuser
MYSQL_PASSWORD: password
And the following pymysql
import pymysql
conn = pymysql.connect(
host='0.0.0.0',
port=6603,
user='testuser',
password='password',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
And received the following error:
OperationalError: (1045, "Access denied for user 'testuser'#'172.18.0.1' (using password: NO)")
The same applies when trying to login as root.
I have tried:
1) Granting privileges in many permutations, also setting up HOST as '%'
2) Removing and recreating the mounted volume
Mainly I want to be able to access the MySQL database from an interactive shell during development.
Any guidance would be great. Thanks.
You should use the IP address 127.0.0.1, or localhost, or your external IP address instead of 0.0.0.0. The address 0.0.0.0 is a special IP address that only makes sense when creating a listening socket, but it makes no sense for creating a connecting socket.

Categories

Resources