Skip to content

Deploying a Dovel App

Dovel is a powerful Laravel and Docker development stack that brings together the best tools for PHP web development. Created as a comprehensive solution for Laravel developers, Dovel combines PHP 7.2, NGINX 1.15, MySQL 8.0.13, and Redis 5.0.0 into a single, cohesive development environment. It’s designed to streamline the setup process and provide a production-ready foundation for Laravel applications.

At its core, Dovel solves the common challenge of environment consistency. Whether you’re developing locally, testing in staging, or deploying to production, Dovel ensures your application runs in the same containerized environment every time. The stack includes everything you need: a modern PHP runtime with essential extensions, a high-performance NGINX web server configured specifically for Laravel, a robust MySQL database for persistent storage, and Redis for caching and session management.

What makes Dovel particularly valuable is its focus on Laravel best practices. The stack is pre-configured with optimized settings for Laravel applications, including proper file permissions, environment variable management, and service dependencies. It eliminates the frustration of mismatched local and production environments while maintaining the flexibility to customize each component to your specific needs.

Why Deploy Dovel on Klutch.sh?

Deploying your Dovel-based Laravel application on Klutch.sh offers several compelling advantages:

  1. Automatic Dockerfile Detection - Klutch.sh recognizes your Dockerfile automatically, building and deploying your Dovel stack without manual intervention or complex configuration steps.

  2. Simplified Multi-Service Architecture - While Dovel typically includes PHP, NGINX, MySQL, and Redis, Klutch.sh’s containerized approach makes it easy to run your consolidated application server while connecting to managed databases.

  3. Persistent Storage for Laravel - Laravel applications need reliable storage for uploads, logs, and storage artifacts. Klutch.sh volumes ensure your data persists across deployments and container restarts.

  4. Environment Variable Management - Configure your Laravel .env settings through Klutch.sh’s dashboard, keeping sensitive credentials secure and making configuration changes without redeploying.

  5. GitHub Integration - Deploy directly from your repository with automatic builds on every push, enabling continuous deployment workflows for your Laravel application.

  6. HTTP Traffic Routing - Klutch.sh’s HTTP traffic support provides seamless routing to your Laravel application running behind NGINX, with automatic SSL certificate management available.

  7. Resource Scaling - Start with minimal resources and scale your Dovel stack as your Laravel application grows, adjusting CPU and memory allocations without infrastructure management.

  8. No Orchestration Complexity - Deploy your multi-container Dovel stack without managing Docker Compose, Kubernetes, or other orchestration tools—Klutch.sh handles it all.

  9. Cost-Effective Development - Run production-grade Laravel applications without the overhead of traditional VPS or managed hosting, paying only for the resources you actually use.

  10. Fast Iteration Cycles - Push code changes to GitHub and see them live in minutes, not hours, with Klutch.sh’s streamlined build and deployment pipeline.

Prerequisites

Before deploying Dovel on Klutch.sh, make sure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your Laravel application
  • Basic understanding of Laravel framework and project structure
  • Familiarity with Docker and containerization concepts
  • Understanding of environment variables and configuration management
  • (Optional) Composer knowledge for dependency management
  • (Optional) Laravel Artisan command experience
  • (Optional) Domain name for custom URL configuration

Dovel Architecture Overview

Understanding Dovel’s architecture helps you optimize your deployment and troubleshoot issues effectively:

Core Components

PHP-FPM Container The PHP 7.2 container runs PHP-FPM (FastCGI Process Manager), which processes PHP scripts for your Laravel application. It includes essential extensions like PDO, mbstring, tokenizer, and JSON that Laravel requires. The container is configured with optimized PHP settings for web applications, including proper memory limits and execution timeouts.

NGINX Web Server NGINX 1.15 serves as the reverse proxy and static file server. It’s configured to forward PHP requests to the PHP-FPM container while serving static assets directly. The NGINX configuration includes Laravel-specific rules for clean URLs, proper caching headers, and security hardening.

MySQL Database MySQL 8.0.13 provides the relational database backend for your Laravel application. It stores user data, application state, and everything your Eloquent ORM models represent. The database container includes performance optimizations and proper character encoding for international applications.

Redis Cache Redis 5.0.0 handles caching and session storage, dramatically improving application performance. Laravel’s cache facade and session driver can leverage Redis for fast, distributed caching across multiple application servers if needed.

Laravel Integration

Application Layer Your Laravel application code lives in the PHP container, with the public directory serving as the web root. Laravel’s routing system handles all HTTP requests, with NGINX passing them through to PHP-FPM.

Configuration Management Environment-specific settings are managed through Laravel’s .env file, which you’ll configure through Klutch.sh’s environment variables. This includes database credentials, cache drivers, session configuration, and application keys.

File Storage Laravel’s storage system includes directories for logs, framework cache, session files, and user uploads. These need persistent volumes to survive container restarts and deployments.

Service Communication

In a traditional Dovel setup, containers communicate through Docker networking. On Klutch.sh, you’ll consolidate the web server and PHP into a single container while connecting to external database and cache services as needed.

Preparing Your Repository

Create a GitHub repository for your Dovel-based Laravel application with this structure:

dovel-laravel-app/
├── Dockerfile
├── docker/
│ └── nginx/
│ └── default.conf
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
├── .env.example
├── artisan
├── composer.json
├── composer.lock
└── README.md

Creating the Dockerfile

For Klutch.sh deployment, create a consolidated Dockerfile that combines PHP and NGINX:

FROM php:7.4-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
nginx \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www/html
# Copy application code
COPY . /var/www/html
# Install Laravel dependencies
RUN composer install --no-dev --optimize-autoloader
# Set permissions
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache
# Copy NGINX configuration
COPY docker/nginx/default.conf /etc/nginx/sites-available/default
# Copy startup script
COPY docker/start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
# Expose port 80
EXPOSE 80
# Start services
CMD ["/usr/local/bin/start.sh"]

NGINX Configuration

Create docker/nginx/default.conf:

server {
listen 80;
listen [::]:80;
server_name _;
root /var/www/html/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}

Startup Script

Create docker/start.sh to start both services:

#!/bin/bash
# Start PHP-FPM in background
php-fpm -D
# Run Laravel optimizations
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Start NGINX in foreground
nginx -g 'daemon off;'

Environment Configuration

Create .env.example with Laravel configuration:

Terminal window
APP_NAME=Dovel
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://example-app.klutch.sh
LOG_CHANNEL=stack
LOG_LEVEL=error
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dovel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=redis
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

Composer Configuration

Ensure your composer.json includes all Laravel dependencies:

{
"name": "laravel/laravel",
"type": "project",
"description": "Dovel Laravel Application",
"keywords": ["framework", "laravel", "dovel"],
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.75",
"laravel/sanctum": "^2.11",
"laravel/tinker": "^2.5",
"predis/predis": "^1.1"
},
"require-dev": {
"facade/ignition": "^2.5",
"fakerphp/faker": "^1.9.1",
"laravel/sail": "^1.0.1",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^5.10",
"phpunit/phpunit": "^9.5.10"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}

Deploying on Klutch.sh

    Create a New Project

    1. Log in to your Klutch.sh dashboard
    2. Click “New Project” to create a container for your Dovel application
    3. Give it a descriptive name like “dovel-laravel-app”

    Connect Your Repository

    1. Click “New Deployment” within your project
    2. Select GitHub as your git source
    3. Authorize Klutch.sh to access your repositories if needed
    4. Choose the repository containing your Dovel Laravel application
    5. Select the branch to deploy (typically main or master)

    Configure Deployment Settings

    Since Dovel serves web traffic through NGINX:

    1. In the deployment settings, select HTTP as the traffic type
    2. Klutch.sh will automatically detect your Dockerfile and build the container
    3. The application will be accessible on the generated URL (e.g., example-app.klutch.sh)
    4. Click “Deploy” to start the build process

    Set Environment Variables

    Configure your Laravel application through environment variables:

    1. Navigate to your deployment’s “Environment” section
    2. Add the following required variables:
    Terminal window
    APP_NAME=Dovel
    APP_ENV=production
    APP_KEY=base64:YOUR_GENERATED_KEY_HERE
    APP_DEBUG=false
    APP_URL=https://your-app.klutch.sh
    DB_CONNECTION=mysql
    DB_HOST=your_database_host
    DB_PORT=3306
    DB_DATABASE=dovel
    DB_USERNAME=your_db_user
    DB_PASSWORD=your_db_password
    CACHE_DRIVER=redis
    SESSION_DRIVER=redis
    QUEUE_CONNECTION=database
    REDIS_HOST=your_redis_host
    REDIS_PASSWORD=your_redis_password
    REDIS_PORT=6379

    Important: Generate your APP_KEY by running php artisan key:generate locally and copying the generated key.

    Attach Persistent Storage

    Laravel applications require persistent storage for several directories:

    1. Navigate to your deployment’s “Storage” section
    2. Click “Add Volume”
    3. Add storage for Laravel’s storage directory:
      • Mount path: /var/www/html/storage
      • Size: 5GB (adjust based on your needs)
    4. Add another volume for logs:
      • Mount path: /var/www/html/storage/logs
      • Size: 2GB
    5. If using local file uploads, add additional storage:
      • Mount path: /var/www/html/public/uploads
      • Size: 10GB (adjust based on expected usage)
    6. Save the volume configuration

    Your deployment will restart automatically with persistent storage attached.

Database Setup

Laravel requires a MySQL database. You have two options on Klutch.sh:

Option 1: Deploy Separate MySQL Container

  1. Create a new deployment in your project for MySQL
  2. Use the official MySQL 8 Docker image
  3. Select TCP traffic type
  4. Configure MySQL environment variables:
Terminal window
MYSQL_ROOT_PASSWORD=your_secure_password
MYSQL_DATABASE=dovel
MYSQL_USER=dovel_user
MYSQL_PASSWORD=user_secure_password
  1. Add persistent volume for MySQL data:

    • Mount path: /var/lib/mysql
    • Size: 10GB
  2. Note the internal connection details and update your Laravel app’s environment variables

Option 2: Use External MySQL Service

Use a managed MySQL service like PlanetScale, AWS RDS, or DigitalOcean Managed Databases:

  1. Create a MySQL database instance
  2. Note the connection credentials (host, port, database, username, password)
  3. Update your Laravel deployment’s environment variables with these credentials
  4. Ensure your database allows connections from Klutch.sh

Redis Setup

For caching and session management, set up Redis:

Option 1: Deploy Redis Container

  1. Create a new deployment for Redis
  2. Use the official Redis Docker image
  3. Select TCP traffic type
  4. Add persistent volume:
    • Mount path: /data
    • Size: 2GB
  5. Configure Redis password through environment variables

Option 2: Use External Redis Service

Use a managed Redis service like Redis Labs, AWS ElastiCache, or Upstash:

  1. Create a Redis instance
  2. Get connection credentials
  3. Update your Laravel environment variables with Redis connection details

Running Database Migrations

After deployment, run Laravel migrations to set up your database schema:

Method 1: Through Deployment Console

If Klutch.sh provides console access:

Terminal window
php artisan migrate --force
php artisan db:seed --force

Method 2: Add to Startup Script

Modify docker/start.sh to run migrations automatically:

#!/bin/bash
# Start PHP-FPM
php-fpm -D
# Wait for database to be ready
until php artisan migrate --force; do
echo "Waiting for database..."
sleep 5
done
# Run seeds if needed
php artisan db:seed --force
# Optimize Laravel
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Start NGINX
nginx -g 'daemon off;'

Method 3: One-Time Setup Job

Create a separate one-time job to run migrations:

  1. Create a temporary Dockerfile that runs migrations
  2. Deploy it once to set up the database
  3. Remove it after successful migration

Configuring Laravel for Production

Cache Configuration

Optimize Laravel’s performance by caching configurations:

In your docker/start.sh, ensure these commands run:

Terminal window
php artisan config:cache
php artisan route:cache
php artisan view:cache

Session Management

Configure Redis for sessions in config/session.php:

'driver' => env('SESSION_DRIVER', 'redis'),
'connection' => 'default',

Queue Configuration

Set up Laravel queues for background jobs:

Update config/queue.php:

'default' => env('QUEUE_CONNECTION', 'redis'),
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],

To process queues, add a queue worker to your startup script:

Terminal window
# Start queue worker in background
php artisan queue:work --sleep=3 --tries=3 &

Create symbolic link for public storage:

In your Dockerfile, add:

RUN php artisan storage:link

File Uploads and Storage

Laravel’s file storage system requires proper configuration:

Local Storage

Configure config/filesystems.php:

'default' => env('FILESYSTEM_DRIVER', 'local'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
],

For production, use S3-compatible storage:

  1. Install S3 package:
Terminal window
composer require league/flysystem-aws-s3-v3
  1. Configure in config/filesystems.php:
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
  1. Add environment variables:
Terminal window
FILESYSTEM_DRIVER=s3
AWS_ACCESS_KEY_ID=your_key
AWS_SECRET_ACCESS_KEY=your_secret
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your_bucket

Logging and Debugging

Configure Laravel Logging

Update config/logging.php for production:

'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'error'),
],
],

Access Logs

View application logs from your persistent storage volume at /var/www/html/storage/logs/laravel.log.

Debug Mode

Never enable debug mode in production:

Terminal window
APP_DEBUG=false
APP_ENV=production

Scheduled Tasks (Cron Jobs)

Laravel’s task scheduler requires a cron job. Add to your startup script:

Terminal window
# Run Laravel scheduler every minute in background
while true; do
php artisan schedule:run
sleep 60
done &

Or create a separate supervisor configuration in your Dockerfile:

# Install supervisor
RUN apt-get update && apt-get install -y supervisor
# Copy supervisor config
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Start supervisor
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

Create docker/supervisord.conf:

[supervisord]
nodaemon=true
[program:php-fpm]
command=php-fpm
autostart=true
autorestart=true
[program:nginx]
command=nginx -g 'daemon off;'
autostart=true
autorestart=true
[program:scheduler]
command=bash -c "while true; do php /var/www/html/artisan schedule:run; sleep 60; done"
autostart=true
autorestart=true
[program:queue-worker]
command=php /var/www/html/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true

Performance Optimization

OPcache Configuration

Enable PHP OPcache for better performance. Create docker/php/opcache.ini:

[opcache]
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1

Copy it in your Dockerfile:

COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/opcache.ini

Database Query Optimization

Enable query logging in development to identify slow queries:

// In AppServiceProvider boot method
if (app()->environment('local')) {
DB::listen(function ($query) {
if ($query->time > 100) {
Log::warning('Slow query', [
'sql' => $query->sql,
'time' => $query->time
]);
}
});
}

Redis Caching Strategy

Cache database queries and computationally expensive operations:

use Illuminate\Support\Facades\Cache;
$users = Cache::remember('active_users', 3600, function () {
return User::where('active', true)->get();
});

Asset Optimization

Compile and minify assets before deployment:

Terminal window
# In your Dockerfile, add:
RUN npm install
RUN npm run production

Security Best Practices

Environment Security

  1. Never commit .env files - Use .env.example as a template
  2. Rotate APP_KEY regularly - Generate new keys periodically
  3. Use strong database passwords - Minimum 16 characters with mixed case, numbers, and symbols
  4. Limit database user permissions - Grant only necessary privileges

Application Security

Update config/app.php:

'debug' => env('APP_DEBUG', false),
'env' => env('APP_ENV', 'production'),

Enable HTTPS in production:

// In AppServiceProvider boot method
if (app()->environment('production')) {
URL::forceScheme('https');
}

CSRF Protection

Ensure CSRF protection is enabled (default in Laravel):

// In VerifyCsrfToken middleware
protected $except = [
// Add any routes that should be exempt
];

Rate Limiting

Configure rate limiting in app/Http/Kernel.php:

protected $middlewareGroups = [
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];

Headers Security

Add security headers to NGINX configuration:

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

Backup and Recovery

Database Backups

Create a backup script docker/backup.sh:

#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/www/html/storage/backups"
mkdir -p $BACKUP_DIR
# Backup database
php artisan db:backup --backup-dir=$BACKUP_DIR --backup-name=db_$DATE.sql
# Compress backup
gzip $BACKUP_DIR/db_$DATE.sql
# Remove backups older than 7 days
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

Application State Backup

Backup uploaded files and storage:

Terminal window
tar -czf storage_backup_$(date +%Y%m%d).tar.gz /var/www/html/storage/app

Automated Backups

Add to your cron schedule in Laravel:

// In App\Console\Kernel
protected function schedule(Schedule $schedule)
{
$schedule->command('db:backup')->daily()->at('02:00');
$schedule->command('cache:clear')->weekly();
}

Recovery Procedures

To restore from backup:

Terminal window
# Restore database
gunzip db_backup.sql.gz
php artisan db:restore --backup-file=db_backup.sql
# Restore files
tar -xzf storage_backup.tar.gz -C /var/www/html/

Troubleshooting

Application Won’t Start

Check logs:

Terminal window
# View Laravel logs
tail -f /var/www/html/storage/logs/laravel.log
# View NGINX error log
tail -f /var/log/nginx/error.log
# View PHP-FPM logs
tail -f /var/log/php7.4-fpm.log

Common issues:

  • Missing .env file or environment variables
  • Incorrect file permissions on storage directories
  • Database connection failures
  • Missing composer dependencies

Solutions:

Terminal window
# Fix permissions
chown -R www-data:www-data /var/www/html/storage
chmod -R 775 /var/www/html/storage
# Clear caches
php artisan cache:clear
php artisan config:clear
php artisan view:clear
# Reinstall dependencies
composer install --no-dev --optimize-autoloader

Database Connection Issues

Symptoms:

  • “SQLSTATE[HY000] [2002] Connection refused” errors
  • Laravel unable to connect to MySQL

Debugging:

Terminal window
# Test database connection
php artisan tinker
>>> DB::connection()->getPdo();
# Check environment variables
php artisan config:show database

Solutions:

  • Verify database host, port, and credentials in environment variables
  • Ensure database server is running and accessible
  • Check firewall rules if using external database
  • Verify database user has proper permissions

500 Internal Server Error

Check:

  • Laravel logs in storage/logs/laravel.log
  • NGINX error logs
  • PHP error logs

Common causes:

  • Missing APP_KEY
  • File permission issues
  • Missing PHP extensions
  • Composer autoload issues

Fix:

Terminal window
# Generate application key
php artisan key:generate
# Rebuild autoloader
composer dump-autoload
# Clear all caches
php artisan optimize:clear

Performance Issues

Slow response times:

Terminal window
# Enable query logging
php artisan telescope:install
php artisan migrate
# Check slow queries
tail -f /var/www/html/storage/logs/laravel.log | grep "Slow query"

High memory usage:

Terminal window
# Check PHP memory limit
php -i | grep memory_limit
# Monitor processes
top -u www-data

Solutions:

  • Enable OPcache
  • Implement Redis caching
  • Optimize database queries with eager loading
  • Use queue workers for heavy tasks

Redis Connection Failures

Symptoms:

  • Session errors
  • Cache failures
  • “Connection refused” errors

Fix:

Terminal window
# Test Redis connection
redis-cli -h your_redis_host -p 6379 ping
# Check Laravel Redis config
php artisan config:show cache.stores.redis

Production Checklist

Before launching your Dovel application:

Configuration

  • APP_ENV set to production
  • APP_DEBUG set to false
  • APP_KEY generated and set
  • Database credentials configured
  • Redis connection configured
  • Mail settings configured
  • File storage configured (S3 recommended)

Security

  • HTTPS enabled
  • Security headers configured in NGINX
  • Strong passwords for all services
  • Database user with limited permissions
  • CSRF protection enabled
  • Rate limiting configured
  • Sensitive data not in logs

Performance

  • OPcache enabled
  • Config cached (php artisan config:cache)
  • Routes cached (php artisan route:cache)
  • Views cached (php artisan view:cache)
  • Redis caching implemented
  • Database indexes optimized
  • Assets minified and compiled

Reliability

  • Persistent volumes configured
  • Database backups automated
  • Error logging enabled
  • Queue workers running
  • Scheduled tasks configured
  • Health checks implemented
  • Monitoring set up

Testing

  • All migrations run successfully
  • Authentication works
  • File uploads functional
  • Email delivery working
  • Scheduled tasks executing
  • Queue jobs processing
  • Cache operations successful

Additional Resources

Conclusion

You’ve successfully deployed a Dovel-based Laravel application on Klutch.sh, bringing together PHP, NGINX, MySQL, and Redis into a production-ready environment. Your Laravel application now benefits from containerization’s consistency, Klutch.sh’s simplified deployment workflow, and the robust architecture that Dovel provides.

With persistent storage ensuring your data survives deployments, environment variables managing your configuration securely, and GitHub integration enabling continuous deployment, you have a professional Laravel hosting setup. The combination of Laravel’s elegant framework, Dovel’s curated stack, and Klutch.sh’s platform creates a powerful foundation for building and scaling web applications.

Remember to monitor your application’s performance, keep dependencies updated, implement regular backups, and follow Laravel best practices as your application grows. Whether you’re building a SaaS product, an e-commerce platform, or a content management system, this Dovel deployment on Klutch.sh provides the reliability and scalability you need to succeed.