Eric
Eric

Reputation: 1261

Test database not found using Laravel sail

I'm using Laravel Sail for the first time and can connect to my database, as well as connect to the test database using TablePlus after changing ports with credentials Host: 127.0.0.1, Port: 3307, User: test_root, Password: test_root. However, when I run

sail test --testsuite Feature --filter=LoginAsTest

I get:

SQLSTATE[HY000] [1049] Unknown database 'test_database' (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')

In my .env file I have:

TEST_DB_CONNECTION=mysql
TEST_DB_HOST=mysql_test
TEST_DB_PORT=3306
TEST_DB_DATABASE=test_database
TEST_DB_USERNAME=test_root
TEST_DB_PASSWORD=test_root

and my docker-compose.yml has:

mysql:
    image: 'mysql:8.0'
    ports:
        - '${FORWARD_DB_PORT:-3306}:3306'
    environment:
        MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
        MYSQL_DATABASE: '${DB_DATABASE}'
        MYSQL_USER: '${DB_USERNAME}'
        MYSQL_PASSWORD: '${DB_PASSWORD}'
        MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    volumes:
        - 'sailmysql:/var/lib/mysql'
    networks:
        - sail
    healthcheck:
      test: ["CMD", "mysqladmin", "ping"]
mysql_test:
  image: "mysql:8.0"
  ports:
    - '${FORWARD_DB_PORT:-3307}:3306'
  environment:
    MYSQL_ROOT_PASSWORD: "${TEST_DB_PASSWORD}"
    MYSQL_DATABASE: "${TEST_DB_DATABASE}"
    MYSQL_USER: "${TEST_DB_USERNAME}"
    MYSQL_PASSWORD: "${TEST_DB_PASSWORD}"
    MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
  networks:
    - sail

Any thoughts as to why I can connect via TablePlus, but not my application?

Update: I've also added:

'mysql_test' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('TEST_DB_PORT', '3306'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_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'),
            ]) : [],
        ],

to my config/database.php

and in my phpunit.xml I have:

 <env name="DB_CONNECTION" value="mysql_test"/>
 <env name="DB_DATABASE" value="test_database"/>

Upvotes: 2

Views: 1692

Answers (1)

jordanvrtanoski
jordanvrtanoski

Reputation: 5537

The docker containers on macOS are running inside a virtual machine that is created by docker-for-mac and the traffic is routed trough the network interface of the virtual machine.

As described in the docker documentation there is no bridge between the macOS and the docker-engine. As consequence, although the docker ps will show the port is published, the container will not be accessible on the localhost of macOS, unless explicitly published on 0.0.0.0.

The difference between the network subsystem of docker running on linux and on macOS is described in this post.

To connect to the containers, easiest way is to use the public IP of the machine, so in your case:

  1. Find the IP of of your machine as described in SO
    ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'
    
  2. Change the connection string to
    'host' => env('DB_HOST', '<<your ip address>>'),
    'port' => env('TEST_DB_PORT', '3307'),
    

Upvotes: 1

Related Questions