Moving Off PaaS: Deploying Production Laravel Stacks with Kamal 2
Platform-as-a-Service (PaaS) providers make launching a web application simple. You push code, and they handle the infrastructure. However, as your application grows, the cost scales aggressively. What starts as a $20/month hobby server can scale to hundreds or thousands of dollars for simple database upgrades, extra RAM, or custom background workers. In the past, moving off a PaaS meant adopting…
Platform-as-a-Service (PaaS) providers simplify launching web applications by handling infrastructure once code is pushed. However, as applications grow, costs rise dramatically due to factors like database upgrades, extra RAM, or custom background workers. Traditionally, moving away from a PaaS involved using complex container orchestrators like Kubernetes or writing custom server setup scripts.
Kamal 2, developed by 37signals, provides an alternative. It is an infrastructure-agnostic deployment tool that enables deploying containerized applications to any virtual private server (such as Hetzner, DigitalOcean, or bare metal) with zero downtime, all using a clean SSH-based workflow. Here's a step-by-step guide to deploying a production Laravel application using Kamal 2.
First, ensure your application is containerized with a production-ready Dockerfile that includes PHP-FPM, Nginx, and necessary PHP extensions. Create this Dockerfile in the root of your Laravel project and specify the required dependencies and configurations. Next, install Kamal on your local development machine using the command `gem install kamal`.
After installation, initiate the deployment process by running `kamal init` in your Laravel project directory. This command generates three crucial files: `config/deploy.yml`, `.env`, and `.kamal/secrets`.
The `config/deploy.yml` file configures your servers, container image registry, and service settings. For a production Laravel app with a Redis server on a single VPS, define your service, image, servers, and registry details in this file. Additionally, manage your environment secrets securely by defining local variables in your `.env` file, such as `KAMAL_REGISTRY_PASSWORD`, `APP_KEY`, and `DB_PASSWORD`.
Kamal retrieves these secrets from your local `.env` file during deployment and injects them into the running container securely.
Finally, execute the first deployment using the command `kamal setup`. This command SSHs into your target server, installs Docker if necessary, sets up Traefik as a reverse proxy, manages accessories like Redis, builds and pushes Docker images, and starts the containers while handling traffic routing. For subsequent updates, use `kamal deploy` for seamless zero-downtime rolling updates.
For additional details, including the full code repository and a security checklist, visit [klytron.com](https://klytron.com/blog/moving-off-paas-kamal-2-laravel).
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.