Server Deployment: From Development to Production

Complete guide to deploying Laravel applications to production servers with zero-downtime deployment, SSL configuration, and performance optimization.

S

StalkTechie

Author

November 26, 2024
1164 views

Server Deployment: From Development to Production

Deploying a Laravel app isn't just FTP-ing files anymore-it's about reliability, security, and scalability. Imagine pushing code without users noticing downtime, auto-scaling during traffic spikes, and sleeping easy knowing SSL and backups are handled. This guide covers the full journey: prep, CI/CD, zero-downtime strategies, SSL, optimization, and monitoring. Tailored for Laravel 11.x in 2025, whether on VPS (DigitalOcean), cloud (AWS), or PaaS (Vercel for APIs). Let's turn your local dev into a battle-hardened production beast.

Preparing Your App for Production

Before deploy, harden and optimize.

  • Env Config: Use .env.production-set APP_ENV=production, APP_DEBUG=false, LOG_CHANNEL=stderr.
  • Composer Optimize: composer install --optimize-autoloader --no-dev-removes dev deps.
  • Cache Everything: php artisan config:cache, route:cache, view:cache, event:cache. Clear with optimize:clear in dev.
  • Storage Permissions: chmod -R 775 storage bootstrap/cache, chown to www-data.
  • Queue/Supervisor: For Horizon or jobs-configure supervisord later.

Security: Enable CSRF, use Sanctum/Fortify. Scan with php artisan security:check (or laravel-security package). Human tip: Version your .env-never commit secrets; use Vault or Forge secrets.

Choosing a Server Environment

  • VPS (e.g., DigitalOcean Droplet): Full control, Ubuntu 22.04+, install LEMP (Nginx, PHP 8.3, MySQL).
  • Cloud (AWS EC2/Lightsail): Scalable, use EB for auto-deploys.
  • PaaS (Laravel Vapor, Forge, Heroku): Serverless-Vapor handles Lambda scaling.
  • Docker/K8s: Containerize for consistency (more below).

Setup basics: SSH key access, firewall (ufw allow 80,443,22), swap file for RAM.

Zero-Downtime Deployment Strategies

Avoid user frustration-use symlinks and atomic swaps.

Manual Script Approach


# On server: deploy.sh
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
npm ci && npm run build  # For assets
ln -sfn /path/to/new/release /path/to/current  # Atomic switch
sudo systemctl reload php-fpm
    

Directories: /var/www/releases/{timestamp}, /var/www/current symlink. Rollback: Point symlink back.

Tools: Envoy, Deployer

Install Deployer: composer require deployer/deployer.


// deploy.php
host('prod')
    ->set('deploy_path', '/var/www/myapp')
    ->set('branch', 'main');

task('deploy', [
    'deploy:prepare',
    'deploy:lock',
    'deploy:release',
    'deploy:update_code',
    'deploy:shared',
    'deploy:vendors',
    'artisan:migrate',
    'deploy:symlink',
    'deploy:unlock',
    'cleanup',
]);

after('deploy:failed', 'deploy:unlock');
    

Run dep deploy prod-handles zero-downtime via symlinks. Envoy for Laravel-native tasks.

Docker and Containerized Deployment

For portability: Multi-stage Dockerfile.


FROM php:8.3-fpm as builder
WORKDIR /app
COPY . .
RUN composer install --no-dev

FROM php:8.3-fpm
COPY --from=builder /app /var/www
CMD ["php-fpm"]
    

Compose with nginx, mysql. Deploy to ECS or Kubernetes: Use rolling updates for zero-downtime.

CI/CD Pipelines

Automate with GitHub Actions:


name: Deploy
on: [push]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with: {php-version: '8.3'}
      - run: composer install --no-dev
      - run: php artisan test
      - name: Deploy to Server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER }}
          key: ${{ secrets.SSH_KEY }}
          script: cd /var/www/myapp && git pull && php artisan migrate --force
    

Test first, then deploy. For Vapor: Serverless, auto-handles.

SSL Configuration and HTTPS

Free certs with Let's Encrypt.


sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
    

In Nginx: Redirect HTTP to HTTPS, HSTS header. Laravel: URL::forceScheme('https'); in AppServiceProvider.

Performance Optimization Post-Deploy

  • Opcache: Enable in php.ini: opcache.enable=1, opcache.memory_consumption=128.
  • Queue Workers: Supervisor config: program:x-laravel-queue{numprocs 8}.
  • CDN: Cloudflare for assets, caching.
  • Database: Indexes, read replicas.
  • Monitoring: Laravel Telescope (dev), Horizon for queues, New Relic/Prometheus.

Tune: php artisan queue:work --daemon, Redis for cache/sessions.

Security and Maintenance

  • Firewall, fail2ban for brute-force.
  • Backups: mysqldump cron, S3 storage.
  • Logs: Rotate with logrotate, monitor with Papertrail.
  • Updates: Regular OS patches, Laravel updates.

Disaster recovery: Test restores quarterly.

Common Pitfalls and Tips

Storage links: php artisan storage:link. Env sync issues-use Forge/Envoyer for managed deploys. Real talk: First deploy nerves? Use staging mirror. Scale: Add load balancer (NGINX) for multi-server.

Deployment done right means focus on building, not fixing. Start with Forge for ease, graduate to custom. Communities like Laracasts have gold-happy deploying!

Share this post:

Related Articles

Discussion

0 comments

Please log in to join the discussion.

Login to Comment