Setup

Two containers: PHP and MySQL. Everything is configured in docker-compose.yml and docker/php/.

First Time Setup

docker compose up -d --build
./dev composer install
docker compose restart php
./dev artisan migrate

App runs at http://localhost:8000.

Subsequent Runs

docker compose up -d

The entrypoint detects vendor/ and starts serving automatically.

Entrypoint

The entrypoint script checks for vendor/ on boot. If it exists, php artisan serve starts in the background. Either way, php-fpm runs as the main process so the container always stays up.

This means on first boot the container is running but not serving until you install dependencies and restart. After that it's fully automatic.

Dependencies aren't installed automatically to avoid modifying composer.lock without your say-so.

The Dev Script

Shortcut for running commands in the PHP container. Handles the artisan case by prepending php.

./dev artisan migrate
./dev artisan make:model Foo -m
./dev composer install
./dev composer require foo/bar
./dev php -v

Make it executable after cloning: chmod +x dev.

Database

The database name, user, and password are set in docker-compose.yml. Your .env needs DB_HOST=mysql (the service name, not localhost) and matching credentials.

Data lives in a named volume so it survives restarts. docker compose down -v wipes it.

Multiple Projects

Everything is scoped by directory name, so projects don't collide. The exception is host ports. Two projects can't both use 8000 simultaneously. Change the port mapping in docker-compose.yml if needed (e.g., "8001:8000").

© Websanova 2026 About Privacy