A Docker set-up for Laravel projects using nginx, PHP-FPM, MySQL, Redis and Node. Also includes xDebug, a basic first route in Laravel (as per their docs), and a running Vite dev server for hot module reloading.
As a minimal starter, this is likely to require scaling during dev (YAGNI for now). Laravel Sail and the official Docker samples may supply Dockerfile guidance when requiring further Laravel-specific server capabilities.
Similar to (and based upon) sibling project Docker Symfony.
The following only needs to be completed when you're setting up the project for the first time. Afterwards, simply (re-)start all required services and containers using the relevant command in Docker Up below.
- Create the .env file with
cp .env.example .envand set required values - Create a Docker-specific .env file with
cp docker/.env.docker.example docker/.env.dockerand set required values - Find and replace all references to
rename-mein this repo to your desired project value
NOTE
DB_HOST/MySQL_HOSThave been set to the MySQL Docker service name:mysql-service, which will resolve automatically via Docker's DNS, but you'll have to ensure database name, user and password variables are also set appropriately.
- To get https working with a self-signed certificate, we'll use mkcert:
# Install mkcert if needed (@link https://github.com/FiloSottile/mkcert)
brew install mkcert
brew install nss # if you use Firefox
# Create root CA (see in Keychain Access app: System > Certificates)
mkcert -install
# Create specific certs
mkcert \
-key-file docker/nginx/certs/rename-me-test-key.pem \
-cert-file docker/nginx/certs/rename-me-test-cert.pem \
rename-me.test- Add the following to your
/etc/hostsfile:
127.0.0.1 rename-me.test
- Run the relevant command in Docker Up below.
- Install dependencies
docker compose exec php-service composer install
- Set the APP_KEY
docker compose exec php-service php artisan key:generate
- Run DB migrations
docker compose exec php-service php artisan migrate
- 'Sync' node_modules - See section below for details.
docker compose cp node-service:/var/www/html/node_modules .
- Url: https://rename-me.test / the first route
- Quickly check the hot module reloading is working by visiting the first route, then changing
resources/css/app.css:14tobackground: green;and seeing the instant change.
- Quickly check the hot module reloading is working by visiting the first route, then changing
# dev (utilizes docker compose override)
docker compose --env-file docker/.env.docker up
# prod
docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file docker/.env.docker upTo start the dev container with xDebug enabled (it's disabled by default), ensure the following is in the .env.docker:
XDEBUG_MODE=debug
- In Settings > PHP, ensure the Debug port matches the port in set in
./docker/php/conf.d/xdebug.ini - In Settings > PHP > Servers, ensure the local app directory is mapped to
/var/www/html, as per the docker set-up.
We are not using the env_file option in docker-compose.yml, because mixing env_file and environment can lead to confusing overrides. You can use env_file alone, but being explicit with environment makes it easy to see which variables each service depends on.
The docker-compose.yml therefore uses the environment key, with values coming from the .env.docker file. This keeps configuration values centralized in one place while still making dependencies visible in the Docker Compose file.
We separate Docker .env files from Laravel .env files on purpose. By the time Laravel runs, the environment variables provided by Docker are already available at the system level inside the container (you can confirm this by inspecting the container).
To inspect which Laravel .env values are present, run the following inside the php-service container:
php artisan tinker
# Now inside Tinker, view all Laravel-specific .env vars with:
Dotenv\Dotenv::createArrayBacked(base_path())->load();The node-service mounts node_modules as a named volume. This mitigates the well‑known macOS file sync speed issues by keeping dependencies inside the container, enabling near‑native Linux filesystem performance for lookups and hot reloads.
Because this volume is isolated from the host, your host node_modules directory won't be hydrated, thus your IDE won't 'see' the installed packages, reporting missing dependencies. To fix this, 'sync' node_modules from the Docker container to your local filesystem with:
docker compose cp node-service:/var/www/html/node_modules .Run this only when dependencies change (e.g. step 6 in Getting Started and after installing any new packages via npm install ..., etc).
Currently, this is dev-focused and would require further work to make prod-ready. At scale, production deployment usually moves beyond Docker Compose toward orchestrators.
- xDebug doesn't work with PhpStorm's test runner
- Right-click on either the test runner icon beside a test or a test directory and select "Modify Run Configuration..." > Click the directory icon in the "Environment variables" input > select the
/docker/.env.dockerfile.- Might require dot files to be shown in the 'open' dialog,
shift+cmd+.on macOS.
- Might require dot files to be shown in the 'open' dialog,
- Right-click on either the test runner icon beside a test or a test directory and select "Modify Run Configuration..." > Click the directory icon in the "Environment variables" input > select the