thedevopser/dockerize-me
Dockerize-me generates Docker configuration for your Laravel app, helping you containerize local development and deployment with minimal setup. A small utility for teams that want a repeatable Docker workflow without hand-writing compose files.
dockerize-me scaffolds Docker assets for a Laravel app — a Dockerfile, docker-compose.yml, .dockerignore, and supporting config (nginx/PHP/entrypoint) — so you don't hand-write them for every project.
Minimal path:
composer require thedevopser/dockerize-me --dev (dev-only; it's a scaffolding tool, not a runtime dependency).php artisan vendor:publish --provider="Thedevopser\DockerizeMe\DockerizeMeServiceProvider" (check php artisan vendor:publish output for the exact tag).php artisan dockerize (confirm the exact signature with php artisan list | grep -i docker — it's the fastest way to see the options for PHP version, DB, and services).docker compose up -d --build and hit the app.Look first at: config/dockerize-me.php (PHP version, DB/cache services, ports, app name) and the published stubs/ directory. The stubs are the real source of truth — the generated files are just rendered output. Read one stub end-to-end before running the command; that tells you more than the README.
First real use case: replacing a hand-maintained docker-compose.yml for local development. Generate, commit, and verify the app boots with MySQL/Redis wired up and php artisan migrate working inside the container.
Separate dev and prod artifacts. Use the generator for a local compose file (bind-mounted source, Xdebug optional, APP_ENV=local), and treat the generated Dockerfile as the base for a multi-stage production build (composer install --no-dev, npm run build, opcache on, no source mount). Don't try to make one compose file serve both.
One image, many services. Build once, then run the same image as app (php-fpm), queue (php artisan queue:work), scheduler (php artisan schedule:work), and nginx. This keeps PHP extensions and code identical across roles and is the pattern that scales to Horizon and Reverb.
Entrypoint for runtime concerns. Put config:cache, route:cache, storage:link, and a DB-wait loop in the entrypoint script rather than the Dockerfile. Anything that needs APP_KEY or DB credentials must happen at container start, not build time.
Commit generated files, regenerate deliberately. Generated output is a snapshot. When the package updates, regenerate on a branch and git diff — treat it like a framework upgrade, not a composer update.
CI. The generated Dockerfile drops straight into a GitHub Actions docker/build-push-action step. Pin the base image tag (e.g. php:8.3-fpm-alpine) in the config rather than accepting a floating latest.
Customize via stubs, not edits. If you need a tweak the config doesn't expose, publish the stub, edit it, and re-run the generator. Editing the generated artifact directly guarantees it gets clobbered on the next run.
v1.5 is a "chore" release with an empty changelog. PR #6 is described only as "Update chore," which is not enough to judge risk. Before upgrading: read the actual diff on GitHub (compare/v1.4...v1.5), and regenerate the files into a scratch branch to see whether stub output changed. If the diff touches stubs, assume your committed Dockerfiles are now stale and review the delta carefully. A "chore" label is not a guarantee of no behavior change in a scaffolding package — stub edits are behavioral.
Re-running the generator overwrites files. Confirm behavior on a throwaway branch first. If it's destructive, keep your real customization in stubs and treat generated files as derived artifacts.
Never bake APP_KEY into the image. Build args persist in image history. Use runtime env / env_file, and keep .env out of the build context via .dockerignore.
File permission pain on Linux. Bind mounts produce host-owned files that www-data can't write. Fix the UID/GID via build args or an entrypoint chown, and make sure storage/ and bootstrap/cache/ are writable — this is the #1 cause of blank pages after up.
depends_on doesn't wait for readiness. Use healthchecks plus depends_on: condition: service_healthy for MySQL/Postgres/Redis, or a wait loop in the entrypoint. Otherwise migrate races the DB on cold start.
Opcache in dev. opcache.validate_timestamps=0 (correct for prod) makes bind-mounted code changes invisible. Keep opcache off or validating in the dev compose override.
Debugging loop: docker compose config to validate interpolation, docker compose logs -f app, docker compose exec app sh to poke around, and check the entrypoint's own output — most failures are env or permissions, not PHP.
Xdebug: ship it as a separate docker-compose.override.yml with a build arg toggle. Enabling it unconditionally makes every request noticeably slower and confuses benchmarks.
Extension points: config/dockerize-me.php for supported toggles, published stubs for structure, and your own base image (FROM your-registry/php-base) if you need extensions the package doesn't offer. Don't fork the package for a missing PHP extension — extend the image instead.
How can I help you explore Laravel packages today?