A real-world account of deploying an existing Laravel application to production using Kamal 2 and Docker without modifying the application itself. Key lessons include: using SSH config aliases instead of raw IP strings for reliable connections with Docker Buildx, setting up a remote builder early when dealing with cross-architecture builds, and treating health check endpoints as a first-class requirement for zero-downtime deployments. Once the process stabilized, deployments became repeatable and predictable, reducing operational stress for the team.
Table of contents
What we were working with: an existing Laravel app in productionWhy we chose Kamal 2 over other Laravel deployment optionsWhere Kamal 2 gets tricky: Docker builds, SSH, and config gotchasWhen Kamal 2 deployment becomes predictable (and why that's the goal)What we learned the hard wayThe app didn't change. The delivery process did.The payoffWhat this means for teams maintaining existing appsResourcesSort: