"Works on my machine" is expensive. The goal of Docker + CI/CD + Coolify is reproducibility: the same artifact that passed tests reaches staging and, when done right, production.
Applies to Laravel APIs, Node apps, modern front ends (including Astro SSR), and, when it makes sense, containerized WordPress. On projects with checkout or gateways, the pipeline is part of the product.
Recommended minimum pipeline
- PR: lint + typecheck + unit tests (and critical e2e if applicable).
- Multi-stage build: dependencies → build → small runtime.
- Immutable tag:
registry/app:gitsha. - Basic image scan.
- Deploy to staging on Coolify with the same variables (different values).
- Smoke / healthcheck.
- Promote to production with the same digest/tag.
Multi-stage (Laravel / Node)
- deps: install Composer/npm with cache.
- build:
npm run build,php artisan optimize, assets. - runtime: final image with non-root user, no toolchain, no secrets.
Details that prevent incidents:
- Ordered layers to avoid invalidating Composer cache on every change.
npm ciin CI, not loosenpm install.- Non-root user + permissions on
storageandbootstrap/cache.
Laravel release checklist
- Multi-stage image with PHP-FPM or Octane.
- Variables in Coolify/CI secrets, never in the image.
- Migrations as an explicit deploy step.
- Queues and scheduler with restart policy.
- Healthcheck: cheap route that verifies app + DB.
- Rollback: redeploy the previous SHA tag.
WordPress in Docker
- Persistent volume for
wp-content/uploads. - Secrets via env / wp-config generated at runtime.
- Object cache (Redis) as a separate service when traffic demands it.
- Multisite: watch domains, cookies, and paths.
- DB + uploads backups before major updates.
Coolify configuration
- Variables and secrets outside the Dockerfile.
- Real healthcheck (HTTP 200, not just "the process exists").
- Domains: canonical apex;
wwwwith 301 redirect. - Let's Encrypt SSL on both hosts.
- Restart policies and accessible logs.
- Staging and production separated.
Pre-production checklist
- Tag = git SHA (not just
latest) - Secrets absent from repo and Docker layers
- Green healthcheck on staging
- Migrations rehearsed + recent backup
- Apex/
wwwand SSL verified - Workers/cron alive after deploy
- Written rollback plan
Common mistakes
- Different rebuild in prod and you no longer know what is running.
- Healthcheck hitting
/with 301 redirect and marking unhealthy in a loop. - WordPress volumes owned by
root. - Running
migrate --forcetwice in parallel. - Forgetting the queue worker: web is up but webhooks are not processed.
A badly deployed checkout is a time bomb. The pipeline connects with payments, and security auditing .