Docker環境のLaravel6で[PDOException]SQLSTATE[HY000] [2002] No such file or directoryと出た時の対処法

docker

こんにちは。

Dockerを使ったLaravelの開発環境を構築していて、

# php artisan migrate

を実行すると、[PDOException]SQLSTATE[HY000] [2002] No such file or directoryとエラーが出て困っていませんか?

この記事では、その原因や対処方法を紹介します。

スポンサーリンク

エラーの原因

このエラーが出るのはは、web用コンテナとDB用コンテナの通信ができていないのが原因です。

エラーの対処法

最終的にdocker-compose.ymlに、必要な記述を書き足していきます。
次の手順でやってみてください。

手順1:MySQLのコンテナに入り、ソケットファイルの場所を確認する

ソケットファイルとは、「.sock」で終わるファイルです。

環境によって、「mysql.sock」だったり、「mysqld.sock」だったりするので、エラーメッセージをよく見てファイル名を確認します。

※僕の場合はmysqld.sockでした。

まずは次のコマンドでMySQLコンテナに入りましょう。

$ docker exec -it MySQLコンテナ名 /bin/bash

調べてみると、mysqld.sockの場所は/var/run/mysqld/mysqld.sockにあるらしい。

早速、ディレクトリを移動して確かめましょう。

# cd /var/run/mysqld/
# ls

lsコマンドで表示されたリスト内に、mysqld.sockがあればOKです!

手順2:docker-compose.ymlを編集する

僕の場合は最終的に次のようなdocker-compose.ymlが出来上がりました。

version: '2'

services:
  laravel_mariadb:
    container_name: laravel_mariadb
    image: mariadb
    ports: 
      - 3306:3306
    volumes:
      - ./docker/mariadbdata:/var/lib/mariadb
      - ./initdb.d:/docker-entrypoint-initdb.d
      - dbsocket:/var/run/mysqld
    environment:
      - MYSQL_ROOT_PASSWORD=Password01
      - DB_SOCKET=/var/run/mysqld/mysqld.sock
    # command: "--innodb_use_native_aio=0"
  laravel_phpmyadmin:
    container_name: laravel_phpmyadmin
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=laravel_mariadb
      - PMA_USER=root
      - PMA_PASSWORD=Password01
    links:
      - laravel_mariadb
    ports:
      - 8088:80
    volumes:
      - ./docker/phpmyadmin/sessions:/sessions
  laravel_php:
    container_name: laravel_php
    build:
      context: .
      dockerfile: dockerfile
    volumes:
      - ./php.ini:/usr/local/etc/php/php.ini
      - ./docker/html:/var/www/html
      - dbsocket:/var/run/mysqld
    links:
      - laravel_mariadb
    ports:
      - 8089:80

volumes:
  mariadbdata:
    driver: local
  dbsocket:

laravel_mariadbコンテナに追加したのは次の部分です。

    volumes:
      - dbsocket:/var/run/mysqld
    environment:
      - MYSQL_ROOT_PASSWORD=Password01
      - DB_SOCKET=/var/run/mysqld/mysqld.sock

laravel_phpコンテナに追加したのは次の部分です。

    volumes:
      - dbsocket:/var/run/mysqld

一番最後にあるvolumes:の部分に、「dbsocket:」を追加します。

volumes:
  mariadbdata:
    driver: local
  dbsocket:

手順3:.envとdatabase.phpを確認する

コンテナ間通信ができても、接続情報が間違っていたら繋がらないので、念のために.envとdatabase.phpも確認しましょう。

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=Password01

database.php

        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'laravel_app'),
            'username' => env('DB_USERNAME', 'root'),
            'password' => env('DB_PASSWORD', 'Password01'),
            'unix_socket' => env('DB_SOCKET', '/var/run/mysqld/mysqld.sock'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_general_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],

最後にコンテナとimageを削除して、docker-compose up -dからphp artisan migrateまでをやり直してみます。

php artisan migrateが正常に完了すれば成功です!

参考

docker-composeコンテナ間でUnixソケット通信をする - Qiita
docker-composeでソケットを共有する共通ボリュームを作成参照したいソケットのあるコンテナのソケット位置を共通ボリュームに接続参照する側のコンテナに共通ボリュームをマウントでOKで…
タイトルとURLをコピーしました