How to expose Linux socket file from Docker container (MySQL, MariaDB, etc.) to host

8,754

The problem is that bind mounts are for exposing something on the host to the container. So when you do this:

volumes:
  - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock

You are trying to mount /srv/docker/sockets/mariadb.container.sock -- which does not exist -- onto /var/run/mysqld/mysqld.sock inside the container. Since the source object doesn't exist, Docker will create an empty directory at that location and mount it into the container...which of course means mysqld can't create the socket when it starts up.

The correct solution is to mount a host directory onto /var/run/mysqld/, for example:

volumes:
  - /srv/docker/sockets/mariadb:/var/run/mysqld

And then on your host the socket will be available as /srv/docker/sockets/mariadb/mysqld.sock.

Share:
8,754

Related videos on Youtube

Torque
Author by

Torque

Updated on September 18, 2022

Comments

  • Torque
    Torque over 1 year

    Disclaimer: I am not looking for a way to configure MySQL/MariaDB to use TCP connections. I am aware of that option and the question is not about that aspect.

    I am having trouble binding a socket file from inside a container to the host file system. I expected a simple docker-compose entry like this to work:

        volumes:
          - /srv/docker/sockets/mariadb.container.sock:/var/run/mysqld/mysqld.sock
    

    But that did not work. Instead, I experienced the following error messages:

    its_sql_dev    | 190305 10:31:23 [ERROR] Can't start server : Bind on unix socket: Address already in use
    its_sql_dev    | 190305 10:31:23 [ERROR] Do you already have another mysqld server running on socket: /var/run/mysqld/mysqld.sock ?
    

    The state of the file in the host system did not seem to matter - wether it already existed, existed with a+rwx permissions, existed with the correct user or did not exist at all did not seem to have any affect on whether the container would start.

    Maybe the most baffling thing was the end result in the host file system:

    [user@server mariadb]# ls -alsh /srv/docker/shared/
    total 16K
    4.0K drwxrwxrwx 4 root    root     4.0K Mar  5 11:31 .
    4.0K drwxr-xr-x 7 root    root     4.0K Mar  1 13:09 ..
    4.0K drwxr-xr-x 2 root    root     4.0K Mar  5 11:31 mariadb.container.sock
    

    It turned out the .sock file turned into an (empty) directory on the host!

    I have had a little more luck with moving the socket file to its own directory amnd mounting that directory to the host, in which case it would work once, but not after a container restart.

  • Torque
    Torque about 5 years
    Thank you, the explanation made it really obvious why it worked that way. And after some debugging, I found out why it only worked once - I was mounting the sock file in a phpMyAdmin container, and after changing the mounting behaviour in the sql container, I didn't think to change it in the phpMyAdmin one as well, leading THAT container to the trigger the directory creation, as it was faster in startup than the sql container.
  • simon
    simon over 2 years
    You may also want to place the socket file in another dir (by changing to socket = /var/run/mysqld-socketdir/mysqld.sock in custom-settings.cnf and attaching it via a custom volume like - ./conf/mysql-conf.d:/etc/mysql/conf.d). This way you will only expose /var/run/mysqld-socketdir to other containers so that other files which are located in /var/run/mysqld will not be accessible to other containers