Skip to content
ExponaBLOG
PHP & LARAVEL DEVELOPMENT · DAY 062 / 100

Laravel Forge and Vapor: a practical PHP & Laravel guide

Managed deployment options.

Expona Admin7 min read

Introduction

By day 62 of your PHP and Laravel journey, you've likely built applications that work great in development but face real hurdles when it comes time to deploy. Choosing how to host and manage your Laravel application is one of the most consequential decisions you'll make, yet many teams treat it as an afterthought. This practical PHP & Laravel guide covers two of the most popular managed deployment options: Laravel Forge and Vapor, alongside a Docker-on-ECS alternative for teams that need more control.

Forge Provisions and Manages Servers

Laravel Forge is a server provisioning and management platform that sits between you and your cloud provider (AWS, DigitalOcean, Linode, or Hetzner). Instead of manually configuring servers, installing Nginx, setting up PHP-FPM, and managing SSL certificates, Forge handles all of that through a clean dashboard and API.

When you create a new server in Forge, it spins up a basic Linux instance on your chosen provider and runs a provisioning script that installs the full stack: Ubuntu system packages, PHP, Nginx, PostgreSQL or MySQL, Redis, and Node.js. Within minutes, you have a production-ready server without ever touching SSH.

Here's what a typical Forge workflow looks like:

  1. Create a server in Forge (choose your cloud provider and region)
  2. Point your domain's DNS to the server's IP
  3. Create a "site" in Forge and link it to your GitHub repository
  4. Forge clones your repo, installs dependencies via Composer, and sets up a deployment script
  5. Push to your main branch, and Forge automatically pulls, installs, and restarts services

The real power of Forge emerges when you need to scale or troubleshoot. You can add a second server and Forge will provision it identically. You can rotate database backups, manage SSL renewal (via Let's Encrypt), view real-time logs, and configure queues and scheduled tasks all from one interface.

For a team running 2–10 Rails applications, Forge typically costs $10–50 per month per server, plus your underlying cloud infrastructure. It's transparent: you see exactly what resources you're paying for at your cloud provider, and Forge adds convenience on top.

The trade-off is that you still manage server updates, disk space, and performance tuning. Forge automates the setup, not the ongoing ops burden entirely.

Vapor Runs Laravel on AWS Lambda

Laravel Vapor takes a fundamentally different approach: it runs your entire Laravel application on AWS Lambda, a serverless compute platform. Rather than renting a server for an hour or a month, you pay only for the CPU and memory your code actually consumes, measured in 100-millisecond increments.

Vapor is designed specifically for Laravel. It packages your application, manages environments, handles cold starts, coordinates databases and queues, and deploys via simple commands. When traffic spikes, Lambda automatically scales to handle it. When traffic drops to zero, you pay nearly nothing.

A typical Vapor deployment flow:

  1. Install the Vapor CLI: composer require --dev laravel/vapor-cli
  2. Run vapor init to configure your environment and AWS credentials
  3. Define your app, database, cache, and queue in a vapor.yml file
  4. Run vapor deploy production, which builds a Docker image, uploads it to AWS ECR, and deploys to Lambda
  5. Each HTTPS request lands on Lambda, your app runs, and the response is returned

Here's a minimal vapor.yml:

php
id: 12345
name: my-app
regions:
  - us-east-1
environments:
  production:
    build:
      - 'composer install'
      - 'php artisan migrate --force'
    memory: 1024
    timeout: 60
    runtime: php-8.1-fpm
    database: my-db
    cache: my-cache
    queue: my-queue

Vapor also manages a RDS database, ElastiCache for caching, and SQS for queues. You don't manually provision or scale any of these—Vapor orchestrates them as part of your deployment.

The advantage is simplicity and cost-efficiency for variable workloads. A low-traffic side project might cost $1–5 per month. A high-traffic app might cost $100–500 per month, but you never over-provision. The downside is vendor lock-in to AWS and potential Lambda cold-start latency (though Vapor's design minimizes this).

Vapor is the most hands-off deployment option; you focus on code, and Vapor handles infrastructure.

Both Handle SSL and Deploy Scripts

Whether you choose Forge or Vapor, SSL certificate management and automated deployments are built in.

Forge and SSL: When you create a site in Forge, you can request a free Let's Encrypt certificate with one click. Forge renews it automatically 30 days before expiration. If you need a custom certificate, you can upload it as well. HTTPS is enforced by default.

Vapor and SSL: Vapor provisions an AWS CloudFront distribution and ACM certificate automatically. Your domain points to CloudFront (a global CDN), which terminates TLS and routes traffic to Lambda. This gives you both SSL and content caching out of the box.

Deployment scripts: Both platforms let you hook into the deployment process. In Forge, you write shell commands that run before or after code is pulled:

php
#!/bin/bash
set -e
cd /home/forge/default
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan storage:link
php artisan migrate --force

In Vapor, your deployment commands live in vapor.yml under the build key, and Vapor runs them inside the Docker image during the build phase, before the image is uploaded to Lambda.

Both platforms also support environment variables, secrets management, and rollback. If a deployment breaks, you can revert to a previous version in seconds.

Docker on ECS for Full Control

Forge and Vapor are excellent defaults, but some teams need more flexibility. Docker containers on AWS ECS (Elastic Container Service) give you that control while still being managed (you don't manage the Kubernetes cluster yourself).

With ECS, you define your application as a Docker image, then run it on a cluster of EC2 instances or Fargate (serverless compute for containers). You scale by adding task definitions, and ECS handles placement and health checks.

A basic Dockerfile for Laravel:

php
FROM php:8.1-fpm

RUN apt-get update && apt-get install -y \
    curl \
    git \
    unzip \
    postgresql-client

COPY composer.lock composer.json ./
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer install --no-dev --optimize-autoloader

COPY . .

RUN php artisan config:cache
RUN php artisan route:cache

EXPOSE 9000

CMD ["php-fpm"]

You'd also define an Nginx container to serve the static assets and reverse-proxy to PHP-FPM. Then, in ECS, you create a task definition that specifies both containers, their memory/CPU, environment variables, and health checks. You launch a service based on that task definition, and ECS ensures the desired number of running tasks at all times.

ECS is more hands-on than Vapor but less hands-on than managing servers directly. You still think about container orchestration, logging, and networking, but you're not managing the underlying infrastructure.

When to reach for ECS: you need custom middleware, non-standard PHP extensions, or the ability to run arbitrary services alongside your app. You're comfortable with Docker and AWS. Your team has enough ops maturity to manage container-based deployments.

Common Mistakes

  • Choosing Forge without estimating server load: Forge hides complexity but still requires you to pick server size upfront. Undersized instances slow down under load; oversized ones waste money. Benchmark locally and gradually scale.
  • Deploying to Vapor without testing Lambda locally: Lambda's environment differs from a traditional server (temporary filesystem, long execution times, cold starts). Use SAM or the Serverless framework locally to catch surprises before production.
  • Not automating database migrations: Whether Forge or Vapor, automate your migration step in the deploy script. Manual migrations are error-prone and prevent true continuous deployment.
  • Forgetting to set environment variables: Both platforms require you to define secrets and config in their dashboards. Missing a variable will only surface when your app crashes in production.
  • Using default database credentials: Always generate strong, random passwords for production databases. Don't reuse development credentials.
  • Ignoring monitoring and logs: Forge and Vapor make deployment easy, but you still need to watch error logs and application metrics. Set up New Relic, Sentry, or CloudWatch alerts so you know when things break.

Key Takeaways

  • Forge provisions and manages traditional servers on your cloud provider, giving you a full Linux stack and SSH access. Ideal for teams wanting simplicity without full serverless complexity.
  • Vapor runs Laravel on AWS Lambda, charging only for actual usage. Best for variable-traffic apps and teams happy to adopt AWS-native services like RDS and SQS.
  • Both handle SSL, automated deployments, and environment secrets. SSL renewal and HTTPS are zero-config in both platforms.
  • Docker on ECS offers a middle ground: containers with managed orchestration. Choose this when Forge feels too hands-on and Vapor too restrictive.
  • Whichever platform you choose, automate deployments, monitor aggressively, and test locally before pushing to production.
  • Start with Forge or Vapor; only graduate to ECS if you have a concrete reason (custom extensions, non-PHP services, or specific AWS features).
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles