A docker based setup for testing with Laravel
I experienced some annoying issues while running integration tests in a Laravel app. The official MySQL docker image will create a user and a database for you which is very convenient, but that user does not have permission to create new databases. I configure my applications to use a separate database for testing, usually with a _testing suffix and so just hit a brick wall.
The solution was to mount an entrypoint script, basically, some SQL statements I want to execute when the container is created. The script will create all of the necessary databases I need.
The file: config/create-databases.sql
CREATE DATABASE IF NOT EXISTS app DEFAULT CHARACTER SET = utf8;
CREATE DATABASE IF NOT EXISTS app_testing DEFAULT CHARACTER SET = utf8;
GRANT ALL PRIVILEGES ON app.* TO 'admin'@'%';
GRANT ALL PRIVILEGES ON app_testing.* TO 'admin'@'%';
FLUSH PRIVILEGES;
My docker-compose.yml
services:
db:
image: mysql/mysql-server:8.0.28
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: admin
MYSQL_PASSWORD: password
cap_add:
- SYS_NICE
ports:
- "127.0.0.1:3306:3306"
volumes:
- db:/var/lib/mysql
- ./config/create-databases.sql:/docker-entrypoint-initdb.d/create-databases.sql
volumes:
db:
Then into .env.testing
I set DB_DATABASE=app_testing
and now I can setup the test database and execute tests.
APP_ENV=testing php artisan migrate
php artisan test
Success!