Laravel has official documentation for running laravel locally here. The documentation doesn't touch on how to use docker. Laradock is a good solution, however it tries to provide everything under the sun. I don't need that. I need simplicity so I can code.
At my previous employer I came up with a pretty slick test rig so that I could do end to end tests with typescript. This post will describe my approach to this.
So first thing I needed to provide was a docker image for this to work. That can be found here. From there a docker-compose.yml
file can be added to your laravel project with the following configuration.
version: '2'
services:
app:
image: kyleparisi/larasible
ports:
- 80:80
environment:
- APP_ENV=testing
volumes:
- ./:/var/www/default
mysql:
image: mysql:5.7
ports:
- 3306:3306
environment:
- MYSQL_DATABASE=homestead
- MYSQL_USER=homestead
- MYSQL_PASSWORD=secret
- MYSQL_ROOT_PASSWORD=secret
One thing I have rarely seen answered is how to do a composer install
without running into permission issues between the host and the container. I later found that you can attach the host user id as the owner and this will allow both the host and the container to work with the vendor
files.
#!/usr/bin/env bash
docker run --rm \
--user $(id -u):$(id -g) \
--volume $PWD:/var/www/default \
--volume $HOME/.composer:/.composer \
--workdir /var/www/default \
--entrypoint "composer" \
kyleparisi/larasible "$@"
I usually add this bash script to ./scripts/composer.sh
and you can run all the typical commands you want. ./scripts/composer.sh install
for example. This is nice because you no longer need any dependencies on the host beyond docker. The same thing can be done for the front end dependencies.
#!/usr/bin/env bash
docker run --rm \
--volume $PWD:/usr/src/app \
--workdir /usr/src/app \
node:8 npm "$@"
So add both scripts to a ./scripts/
directory in your laravel project and make them executable.
chmod +x ./scripts/composer.sh
chmod +x ./scripts/npm.sh
Add a .env.testing
file to your laravel project which will be used in our test rig.
APP_ENV=testing
APP_KEY=base64:blahblah
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
Now for the meat and potatoes.
#!/usr/bin/env bash
set -e
[ -f ".env.testing" ] || $(echo Please make an .env.testing file and run: php artisan key:generate --env=testing; exit 1)
export $(cat .env.testing | grep -v ^# | xargs);
echo Starting services
docker-compose up -d
echo Host: 127.0.0.1
until docker-compose exec mysql mysql -h 127.0.0.1 -u $DB_USERNAME -p$DB_PASSWORD -D $DB_DATABASE --silent -e "show databases;"
do
echo "Waiting for database connection..."
sleep 5
done
echo Installing dependencies
./scripts/npm.sh install
./scripts/composer.sh install
echo Seeding database
rm -f bootstrap/cache/*.php
docker-compose exec app php artisan migrate --env=testing && echo Database migrated
docker-compose exec app php artisan db:seed --env=testing && echo Database seeded
Add the above script to the root of your laravel project as testrig.sh
and also make it executable. This script does everything you need to run your laravel project. It starts up the servers, ensures the database is booted, installs dependencies, runs database migrations, and runs database seeds. These services are exposed to your computer on the standard ports.
./testrig.sh
Visit http://localhost
when the script is done to see the laravel welcome screen. Mysql can be found on port 3306
. If you had snazzy end to end tests you could add your test command to the end of the testrig.sh
file. For example npm test
.
From here you can do your "test driven development" or regular development using this test rig. When your done for the day, clean up is super simple.
docker-compose stop && docker-compose rm
Hopefully you'll find this method faster than the official options and simpler than laradock
.