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/andbootstrap/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 codevendor/— PHP dependencies (production only)public/build/— Compiled CSS/JS assetsresources/views/— Blade templatesdatabase/migrations/,database/seeders/— Database setupstorage/— 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
artisanfile is located.
4. Create the Storage Link
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):
- Manually copy the contents of
storage/app/public/topublic/storage/ - Or create the link through your hosting panel's file manager
- 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.exampleusesdatabasefor bothCACHE_STOREandSESSION_DRIVER. On shared hosting,fileis 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 |
symlink Disabled
If symlink() is disabled, you can't run php artisan storage:link. Instead:
- Create a
storagefolder insidepublic/ - Copy uploaded files from
storage/app/public/topublic/storage/manually - 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:
- Go to Domains or Addon Domains
- Set the document root to
/home/username/cms/public
Without Document Root Control
If your host only serves from public_html/:
- Upload all CMS files to a directory outside
public_html/(e.g.,/home/username/cms/) - Copy the contents of
public/intopublic_html/ - Edit
public_html/index.phpto 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:
- Set
APP_URL=https://yourdomain.comin.env - Enable
general.force_httpsin Settings > General - 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:
- Run the install wizard to configure the new database connection
- Import the included database:
- SQLite: The file is at
database/database.sqlite— setDB_CONNECTION=sqlitein.env - MySQL: Import
database/export-dump.sqlvia phpMyAdmin or your host's MySQL import tool
- SQLite: The file is at
- Verify uploaded media files are accessible at
public/storage/
Related
- Requirements — Full server requirements
- Installation — Installation guide
- Configuration — System configuration
- Cache Management — Cache optimization