~/blog $ ./index.sh
| 6 min read | 5 views | 0 likes | 0 comments

./Deploy Laravel on VPS with Caddy.md

// Getting your Laravel app live on a VPS doesn't have to be complicated. This guide walks you through deploying Laravel using the Caddy web server

Getting your Laravel app live on a VPS doesn't have to be complicated. This guide walks you through deploying Laravel using Caddy web server, which handles SSL certificates automatically and has a much simpler configuration than Nginx or Apache.

What You Need

  • Ubuntu VPS (22.04 or 24.04)

  • A domain name

  • SSH access to your server

  • Your Laravel project

Step 1: Update Your System

Always start with a fresh package list:

sudo apt update

Step 2: Install PHP and Required Extensions

Laravel needs PHP along with several extensions to function properly. Install them all at once:

sudo apt install php php-cli php-common php-mysql php-zip php-gd php-mbstring php-curl php-xml

Here's what each extension does:

  • php-cli - Run artisan commands from terminal

  • php-mysql - Database connectivity

  • php-zip - Composer dependency management

  • php-gd - Image processing

  • php-mbstring - String handling for internationalization

  • php-curl - HTTP requests

  • php-xml - XML parsing (many packages require this)

Verify the installation:

php -v

You should see PHP 8.3.x (or your installed version).

Step 3: Install PHP-FPM

PHP-FPM (FastCGI Process Manager) is the recommended way to run PHP with modern web servers. It's more efficient and handles concurrent requests better:

sudo apt install php8.3-fpm php8.3-mysql php8.3-xml php8.3-curl php8.3-mbstring php8.3-zip php8.3-gd unzip

Enable and start the service:

sudo systemctl enable --now php8.3-fpm

Step 4: Install Composer

Composer manages PHP dependencies. Install it globally:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Confirm it's working:

composer --version

Step 5: Upload Your Laravel Application

Navigate to the web directory:

cd /var/www

Clone your repository or upload your files:

git clone https://github.com/yourusername/your-repo.git laravel-app
cd laravel-app

If you're not using Git, you can upload files via SFTP to /var/www/laravel-app.

Step 6: Install Dependencies

Install PHP packages without development dependencies:

composer install --no-dev --optimize-autoloader

The --no-dev flag skips testing and development packages, while --optimize-autoloader improves performance.

If your app uses Vite or another frontend build tool:

npm install
npm run build

Step 7: Configure Environment

Create your environment file:

cp .env.example .env

Edit the file with your production settings:

nano .env

Important settings to update:

  • APP_ENV=production

  • APP_DEBUG=false (critical for security)

  • Database credentials (DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD)

  • APP_URL with your actual domain

  • Any third-party API keys

Generate the application encryption key:

php artisan key:generate

Create the symbolic link for file storage:

php artisan storage:link

Step 8: Optimize Laravel

Cache your configuration files for better performance:

php artisan config:cache
php artisan route:cache
php artisan view:cache

This compiles your config, routes, and Blade templates into cached files.

Step 9: Database Setup

Run your migrations:

php artisan migrate --force

The --force flag is required in production environments.

If you need to seed initial data:

php artisan db:seed --force

Step 10: Set Correct Permissions

Laravel needs write access to specific directories. Set the correct ownership:

sudo chown -R www-data:www-data /var/www/laravel-app/storage
sudo chown -R www-data:www-data /var/www/laravel-app/bootstrap/cache

Set appropriate permissions:

sudo chmod -R 775 /var/www/laravel-app/storage
sudo chmod -R 775 /var/www/laravel-app/bootstrap/cache

These permissions allow the web server to write logs, cache files, and uploaded content.

Step 11: Install Caddy

Add Caddy's repository and install:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Step 12: Configure DNS

Before configuring Caddy, point your domain to your VPS. Add an A record in your DNS settings:

Type: A
Name: blog (or @ for root domain)
Value: Your VPS IP address
TTL: 3600

Step 13: Configure Caddy

Edit the Caddyfile:

sudo nano /etc/caddy/Caddyfile

Replace the contents with your Laravel configuration:

blog.yourdomain.com {
    root * /var/www/laravel-app/public
    
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
    encode gzip
    
    request_body {
        max_size 10MB
    }
    
    header {
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        Referrer-Policy "no-referrer-when-downgrade"
        -Server
    }
    
    log {
        output file /var/log/caddy/blog.log
        level INFO
    }
}

Key configuration elements:

  • root - Points to Laravel's public directory

  • php_fastcgi - Connects to PHP-FPM via Unix socket

  • file_server - Serves static assets (CSS, JS, images)

  • encode gzip - Compresses responses

  • request_body - Sets maximum upload size

  • header - Adds security headers

  • log - Enables access logging

Adjust max_size if you need to handle larger file uploads.

Step 14: Start Caddy

Reload Caddy with your new configuration:

sudo systemctl reload caddy

Check that it's running properly:

sudo systemctl status caddy

You should see "active (running)" status.

The best part? Caddy automatically obtains and renews SSL certificates from Let's Encrypt. No manual certificate management needed.

Step 15: Access Your Application

Open your browser and visit:

https://blog.yourdomain.com

You should see your Laravel application running with HTTPS enabled (green padlock in the address bar).

Troubleshooting Common Issues

502 Bad Gateway Error

This indicates PHP-FPM isn't running properly. Check its status:

sudo systemctl status php8.3-fpm

If it's not running, start it:

sudo systemctl start php8.3-fpm

500 Internal Server Error

Check Laravel's logs for detailed error information:

tail -f /var/www/laravel-app/storage/logs/laravel.log

Common causes:

  • Incorrect file permissions

  • Database connection issues

  • Missing or misconfigured .env file

  • Cache issues (try clearing with php artisan cache:clear)

Missing Images or Uploaded Files

The storage link might be broken. Recreate it:

cd /var/www/laravel-app
php artisan storage:link

Caddy Won't Start

Check Caddy's logs for configuration errors:

sudo journalctl -u caddy --no-pager | tail -50

Common issues:

  • Domain not pointing to server yet

  • Port 80/443 already in use by another service

  • Syntax error in Caddyfile

Deploying Updates

When you need to deploy changes, follow this workflow:

cd /var/www/laravel-app

# Enable maintenance mode
php artisan down

# Pull latest changes
git pull origin main

# Update dependencies
composer install --no-dev --optimize-autoloader
npm install
npm run build

# Clear old caches
php artisan config:clear
php artisan cache:clear
php artisan view:clear

# Rebuild caches
php artisan config:cache
php artisan route:cache
php artisan view:cache

# Run new migrations
php artisan migrate --force

# Disable maintenance mode
php artisan up

# Restart PHP-FPM
sudo systemctl reload php8.3-fpm

You can save this as a shell script for faster deployments.


Wrapping Up

Your Laravel application is now live on your VPS with automatic HTTPS courtesy of Caddy. The setup provides a solid foundation for production hosting with minimal configuration overhead.

$ comments.log // 0 Comments

// No comments yet. Be the first to comment.
./subscribe.sh

# Get new posts via email. No spam.

$