I am using Docker 19.03.8 and want to setup two containers:
Both containers share the same network via the networks
statement. (I can not bind mount the mysqld socket directly into the PHP container, as the MySQL versions are different, therefore the MySQL container).
This is my docker-compose.yml file:
...
database:
build: .
volumes:
- /var/run/mysqld/mysqld.sock:/tmp/mysql.sock
...
The Dockerfile for MySQL:
FROM mysql:8.0.20
COPY my.cnf /etc/mysql/my.cnf
And the my.cnf file contains:
...
[mysql]
socket = /tmp/mysql.sock
[mysqld]
socket = /tmp/mysql.sock
...
Unfortunately I get this error message from the MySQL container:
2020-05-20T11:30:04.708067Z 0 [ERROR] [MY-010270] [Server] Can't start server : Bind on unix socket: Address already in use
2020-05-20T11:30:04.708406Z 0 [ERROR] [MY-010258] [Server] Do you already have another mysqld server running on socket: /tmp/mysql.sock ?
2020-05-20T11:30:04.709083Z 0 [ERROR] [MY-010119] [Server] Aborting
The MySQL container starts with no errors, if I leave out socket = /tmp/mysql.sock
from the [mysqld]
section in my.cnf. But if I then try to connect to the database from the PHP container (mysql -h <what I specified in the networks statement> -u <user> -p <password>
) I just get an empty database. So I assume it uses the default socket (/var/run/mysqld/mysqld.sock).
I don't understand why this is not working, I would be really grateful if anyone could give me a hint.
You should use a TCP connection for this. Configure the PHP container to connect to the Compose service name (database
) and default MySQL port (3306) for the database container. Do not try to use a Unix socket here.
This setup should work with the out-of-the-box mysql:8
and Docker Compose configurations. You do not need a custom my.cnf
or Compose networks:
, container_name:
, links:
, or other options.
The important detail in the setup you show is that the MySQL daemon must create the socket file itself. If you really want to do this using a Unix socket, you need to bind-mount the directory containing the socket file; you can't bind-mount the socket itself. (You could also in principle use a named volume here.)
# Not the preferred path: mount a directory instead of a file
volumes:
- ./shared_tmp:/tmp
With the setup you show, you'll hit the following sequence of events:
database
container./var/run/mysqld/mysqld.sock
doesn't exist on the host, so it creates an empty directory there and mounts it into the container./tmp/mysql.sock
, but there is already a (empty) directory there.In general it's better to avoid trying to communicate between containers via the filesystem. In addition to complications like these, there are frequently user-permission issues, and this setup limits your ability to run on multi-host setups like Docker Swarm and Kubernetes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With