Skip to main content

Laravel

The php-ci base image has everything a Laravel test run needs out of the box: Composer 2, PHPUnit, and the pdo_mysql, pdo_pgsql, pdo_sqlite, bcmath, mbstring, intl and gd extensions Laravel commonly depends on.

Image tag

docker pull himanshuramavat/php-ci:8.3
# Or from GitHub Container Registry:
docker pull ghcr.io/himanshuramavat/php-ci:8.3

Use the base image tag for Laravel.

Fast path: SQLite in-memory

The quickest CI configuration runs the suite against an in-memory SQLite database — no service container required. Set this in phpunit.xml:

<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_STORE" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
</php>

Then run:

docker run --rm -v "$(pwd):/app" -w /app himanshuramavat/php-ci:8.3 \
bash -c "composer install --no-interaction --prefer-dist && \
cp .env.example .env && php artisan key:generate && \
php artisan test"

PHPUnit directly

php artisan test is a friendly wrapper, but you can call PHPUnit too:

docker run --rm -v "$(pwd):/app" -w /app himanshuramavat/php-ci:8.3 \
bash -c "composer install --no-interaction && ./vendor/bin/phpunit"

Pest

If your project uses Pest, the binary is installed by Composer like any other dev dependency:

docker run --rm -v "$(pwd):/app" -w /app himanshuramavat/php-ci:8.3 \
bash -c "composer install --no-interaction && ./vendor/bin/pest"

GitHub Actions example (MySQL service)

name: Laravel CI
on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
container:
image: himanshuramavat/php-ci:8.3
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel_test
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping" --health-interval=10s
--health-timeout=5s --health-retries=5
env:
DB_CONNECTION: mysql
DB_HOST: mysql
DB_DATABASE: laravel_test
DB_USERNAME: root
DB_PASSWORD: root
steps:
- uses: actions/checkout@v4
- run: composer install --no-interaction --no-progress --prefer-dist
- run: cp .env.example .env && php artisan key:generate
- run: php artisan migrate --force
- run: php artisan test
{
"scripts": {
"test": "@php artisan test",
"lint": "pint --test",
"ci": ["@lint", "@test"]
}
}

Tips

  • Cache the Composer download directory between CI runs to cut install time — see GitHub Actions caching.
  • Run database migrations with --force in CI so they execute in the non-interactive testing/production-like environment.
  • For static analysis, Larastan runs on the bundled PHPStan binary with no extra system packages.