I have a MySQL server v8.4 running in Google Cloud with skip-name-resolve
. It requires SSL connections, but without trusted client certificates.
I have a user configured on the server to connect from any IP: 'myuser'@'%'
.
I have verified the user can connect from any IP using the mysql
DB where SELECT Host, User FROM user
returns:
+-----------+----------------------------+
| Host | User |
+-----------+----------------------------+
| % | myuser |
| % | root |
+-----------+----------------------------+
For Google Cloud config, connections are allowed from any IP, set using the CIDR range 0.0.0.0/0
.
I have a Python program using SQLAlchemy to connect to the server:
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
with Session(create_engine('mysql://myuser:mypass@X.X.X.X:3306/mydb?ssl=true')) as session:
result = session.query(MyTable).all()
print(result)
When running on my local machine, this connects to the remote server without issue and prints the rows. Using a VPN and switching to various IP addresses, this continues to work.
As soon as I put this client code inside a Docker container, the server starts denying the connections.
sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1045, "Access denied for user 'myuser'@'Y.Y.Y.Y' (using password: YES)")
Y.Y.Y.Y
matches my public IP address exactly. Connecting from outside the Docker container from this same IP address does not have any issues.
My Dockerfile:
FROM python:3.12-slim-bullseye
WORKDIR /usr/src/app
ENV PYTHONPATH=.
COPY requirements.txt requirements.txt
COPY myfile.py myfile.py
RUN apt-get update && apt-get install -y pkg-config default-libmysqlclient-dev
RUN pip3 install -r requirements.txt
CMD python3 myfile.py
The database logs show that the request is reaching the server but provides no additional information:
Access denied for user 'myuser'@'Y.Y.Y.Y' (using password: YES)
Disabling the SSL requirement on the server fixes the issue. So it seems that the container is ignoring the ?ssl=true
.
How do I get the container's connection to use SSL?
In your connection string, add ?ssl_mode=REQUIRED
instead of ?ssl=true
. This is the syntax for libmysqlclient
(MySQL docs confusingly refer to ssl-mode
and sslMode
which are not available with libmysqlclient
).