docker-compose run mysql: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

1.3k Views Asked by At

I'm totally roasted after working 14 hours straight, and even after crawling the whole internet I'm unable to resolve this problem.

The scene is imaginable simple:

I have a docker-compose.yml with many services required to install and deploy an app, amongst them a simple MySQL 5 service:

  (...)
  mysql:
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_ROOT_PASSWORD: 
    image: mysql:5
    restart: always
    volumes:
      - .mysql:/var/lib/mysql
  (...)

Now I just want to create the initial database before deploying the app, with a simple:

docker-compose run mysql mysql -e "CREATE DATABASE IF NOT EXISTS database"

But whatever I try I get this error:

Creating network "app_default" with the default driver
Creating app_mysql_run ... done
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

I also tried (without success / with the same error message):

docker-compose up -d mysql
docker-compose exec mysql mysql -e "CREATE DATABASE IF NOT EXISTS database"

The only thing that works is entering the container and manually executing the exact(!) same(!) command. But I absolutely need to automate it.

What am I missing? Any kind of help is highly appreciated!

1

There are 1 best solutions below

0
Marcello Mönkemeyer On

Turns out docker-compose run and docker-compose exec overwrite the commands of the Dockerfile, thus mysqld is never started. Passing mysqld && mysql -e "CREATE DATABASE database" doesn't work, and running docker-compose exec after docker-compose up will result in a race condition.

I ended up with the following solution, which suits my needs:

docker-compose run mysql && \
docker-compose exec mysql /bin/bash -c "while ! mysql -e \"CREATE DATABASE IF NOT EXISTS database\" &> /dev/null; do sleep 1; done"

This will loop the command on a child container until the host container is ready. Also, IF NOT EXISTS is important here, otherwise it may run into a deadlock if the database already exists.