Shared Hosting Deployment

Unfold CMS is designed to work on standard shared hosting environments without queue workers, background processes, or special server configurations. This guide covers everything you need to deploy and run Unfold CMS on shared hosting.

Shared Hosting Compatibility

Unfold CMS runs entirely on synchronous execution:

Feature How It Works
Task execution All tasks run synchronously (no queue workers)
Scheduled posts Published by a single cron entry
Sitemap generation Regenerated on content save
Email sending Sent synchronously on trigger
Backups Created synchronously on demand
Cache File-based cache (no Redis required)

Requirements

Most shared hosting providers meet these requirements out of the box:

  • PHP 8.2+ with common extensions
  • MySQL 8.0+ (provided by most hosts)
  • File system write access to storage/ and bootstrap/cache/
  • At least one cron job slot

See Server Requirements for the complete list.

Exporting for Shared Hosting

The cms:export command packages your CMS into a ready-to-upload zip. You build locally (where you have shell access, Node, Composer) and upload the result — no shell access needed on the hosting server.

Quick Start

# Standard export
php artisan cms:export

# Preview what will be included
php artisan cms:export --dry-run

# Include media and database for site migration
php artisan cms:export --include-uploads --include-database

The zip will be created in storage/app/exports/.

Using the Helper Script

For convenience, a helper script checks prerequisites and runs the export:

./export.sh
./export.sh --include-uploads --include-database

Command Options

Option Description
--output=<path> Custom output directory (default: storage/app/exports)
--include-uploads Include uploaded media files from storage/app/public/
--include-database Include a database dump (SQLite file or MySQL dump)
--no-build Skip frontend build, use existing public/build/
--dry-run Preview what will be exported without creating a zip

What's in the Zip

The exported zip contains everything needed to run the CMS:

  • app/, config/, routes/, bootstrap/ — Application code
  • vendor/ — PHP dependencies (production only)
  • public/build/ — Compiled CSS/JS assets
  • resources/views/ — Blade templates
  • database/migrations/, database/seeders/ — Database setup
  • storage/ — Empty directory structure with correct permissions
  • .env.example — Environment template

Frontend source files (resources/js/, resources/css/, node_modules/) are not included — only the compiled output in public/build/.

Deployment Steps

1. Upload Files

Upload the exported zip to your hosting account via cPanel File Manager, FTP/SFTP, or SSH. Extract it on the server.

Your web server must serve from the public/ directory. How you achieve this depends on your host — see Document Root Configuration below for all options.

2. Run the Installation Wizard

Visit https://yourdomain.com/install (or https://yourdomain.com/public/install if your document root isn't configured) and follow the installation wizard.

3. Configure the Cron Job

Add a single cron job through your hosting panel (cPanel, Plesk, etc.):

* * * * * cd /home/username/public_html && php artisan schedule:run >> /dev/null 2>&1

This handles all scheduled tasks including:

  • Publishing scheduled blog posts (every minute)
  • License verification (daily)
  • Scheduled backups (Pro)

Note: Adjust the path to match your CMS installation directory. The path should be where the artisan file is located.

The storage link connects public/storage to storage/app/public for serving uploaded files.

If symlink is available:

php artisan storage:link

If symlink is disabled (common on shared hosting):

  1. Manually copy the contents of storage/app/public/ to public/storage/
  2. Or create the link through your hosting panel's file manager
  3. Or ask your hosting provider to create the symlink

5. Set Permissions

Ensure these directories are writable (chmod 775):

storage/
storage/app/
storage/app/public/
storage/framework/
storage/framework/cache/
storage/framework/sessions/
storage/framework/views/
storage/logs/
bootstrap/cache/
public/uploads/

Most shared hosts set these correctly by default. Use your hosting panel's file manager to adjust permissions if needed.

Environment Configuration

Essential .env Settings

APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

# Sync queue (no workers needed)
QUEUE_CONNECTION=sync

# File-based drivers (no Redis needed)
CACHE_STORE=file
SESSION_DRIVER=file

Note: The default .env.example uses database for both CACHE_STORE and SESSION_DRIVER. On shared hosting, file is recommended for simpler setup and fewer database queries.

Performance Optimization

After installation, cache your configuration for better performance:

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

If SSH is not available, the CMS provides cache management through the admin panel at Tools > Cache.

Common Shared Hosting Issues

proc_open / exec Disabled

Many shared hosts disable proc_open, exec, and shell_exec. Unfold CMS works without these functions:

Feature With proc_open Without proc_open
Installation wizard Full functionality Full functionality
Content management Full functionality Full functionality
Cache clearing Via admin panel Via admin panel
Artisan commands Via SSH or cron Via cron only

If symlink() is disabled, you can't run php artisan storage:link. Instead:

  1. Create a storage folder inside public/
  2. Copy uploaded files from storage/app/public/ to public/storage/ manually
  3. Or contact your host to enable symlinks

PHP Memory Limit

If you encounter memory errors, contact your host about increasing the PHP memory limit to at least 128MB (256MB recommended).

Max Execution Time

Long operations (like creating backups) may hit the default 30-second timeout. Request your host increase max_execution_time to at least 60 seconds.

File Upload Size

If file uploads fail, check that upload_max_filesize and post_max_size in PHP are set to at least 10M. These can often be configured through .htaccess:

php_value upload_max_filesize 64M
php_value post_max_size 64M

Or through php.ini / hosting panel PHP settings.

Document Root Configuration

Ideal Setup

The ideal configuration points your domain's document root to the public/ directory:

/home/username/cms/          → CMS root
/home/username/cms/public/   → Document root (domain points here)

cPanel with Addon Domain

If using cPanel, you can set the document root when adding the domain:

  1. Go to Domains or Addon Domains
  2. Set the document root to /home/username/cms/public

Without Document Root Control

If your host only serves from public_html/:

  1. Upload all CMS files to a directory outside public_html/ (e.g., /home/username/cms/)
  2. Copy the contents of public/ into public_html/
  3. Edit public_html/index.php to update the paths:
// Maintenance mode check
if (file_exists($maintenance = __DIR__.'/../cms/storage/framework/maintenance.php')) {
    require $maintenance;
}

// Autoloader and bootstrap — point to your CMS root
require __DIR__.'/../cms/vendor/autoload.php';
$app = require_once __DIR__.'/../cms/bootstrap/app.php';

$app->handleRequest(Illuminate\Http\Request::capture());

SSL / HTTPS

Most shared hosts provide free SSL through Let's Encrypt. After enabling SSL:

  1. Set APP_URL=https://yourdomain.com in .env
  2. Enable general.force_https in Settings > General
  3. Clear the config cache

Site Migration

To move an existing Unfold CMS site to a new host:

php artisan cms:export --include-uploads --include-database

After uploading and extracting:

  1. Run the install wizard to configure the new database connection
  2. Import the included database:
    • SQLite: The file is at database/database.sqlite — set DB_CONNECTION=sqlite in .env
    • MySQL: Import database/export-dump.sql via phpMyAdmin or your host's MySQL import tool
  3. Verify uploaded media files are accessible at public/storage/