Statamic Guide
Statamic is a powerful flat-file CMS that’s perfect for the Webslice Serverless platform. With proper configuration, you can achieve excellent performance and keep costs low by leveraging Statamic’s built-in static caching features. This guide will walk you through deploying and optimizing your Statamic site on Webslice Serverless.
Before You Begin
This guide assumes you already have a Statamic site ready to deploy. If you’re starting fresh, check out the official Statamic documentation to get your site set up locally first.
Key Concepts for Serverless Deployments
Atomic Git Deployments
When you deploy to Webslice Serverless via git, your deployments are atomic. This means:
- Each deployment is built in isolation and switched over instantly when ready
- There’s no downtime during deployments
- If a deployment fails, your previous version continues running
- Your live site always has a complete, working codebase
This is important for Statamic because it means you can confidently deploy updates without worrying about incomplete file uploads or partial deployments interrupting your site.
Understanding Storage and Atomic Deployments
Because deployments are atomic, each deployment brings a fresh copy of your git repository. This means:
- Your application directory is replaced entirely with each deployment
- Any files written to your application directory during runtime (uploads, cache, logs) will be lost on the next deployment
- Files not in your git repository won’t carry over between deployments
That’s where the /mnt/data/website/shared directory comes in – it’s a persistent directory that exists outside your application’s deployment directory and survives across all deployments. This is where you store user-generated content, uploads, caches, and anything else that needs to persist between deployments.
Configuration for Optimal Performance
Static Caching Setup
Statamic’s static caching is your best friend on a serverless platform. It pre-generates HTML files for your pages, which means:
- Lightning-fast page loads
- Minimal PHP execution
- Lower costs (fewer invocations)
- Better performance under traffic spikes
First, enable static caching in your config/statamic/static_caching.php:
return [ 'strategy' => 'full',
'strategies' => [ 'full' => [ 'driver' => 'file', 'path' => storage_path('statamic/static'),
'lock_hold_length' => 0,
'permissions' => [ 'directory' => 0755, 'file' => 0644, ],
'warm_concurrency' => 25,
'warm_queue' => env('STATAMIC_STATIC_WARM_QUEUE'), ], ],
'servers' => [],
'invalidation' => [ 'class' => null, 'rules' => 'all', ],
'ignores' => null,
'replacers' => [ 'csrf' => \Statamic\StaticCaching\Replacers\CsrfTokenReplacer::class, 'nocache' => \Statamic\StaticCaching\Replacers\NoCacheReplacer::class, ],
'warm_queued' => true,];The key settings here are:
strategyset to'full'for maximum cachingdriverset to'file'which works well on serverlesswarm_concurrencyat6for efficient cache warming
Environment Variables
Add these to your .env file:
STATAMIC_STATIC_CACHING_STRATEGY=fullSTATAMIC_STATIC_WARM_QUEUE=trueSTATAMIC_STACHE_WATCHER=fileSTATAMIC_REVISIONS_ENABLED=falseThese settings optimize Statamic for serverless deployments by enabling full static caching and disabling features that work better with persistent file systems.
Persistent Storage Configuration
Directory Structure
You’ll want to store several types of data in the persistent /mnt/data/website/shared directory:
Directorymnt/website/shared/
Directoryassets/ Asset containers (images, documents, etc.)
- …
Directoryforms/ Form submissions
- …
Directoryglide-cache/ Image manipulation cache
- …
Directorylogs/ Application logs
- …
Directoryusers/ User accounts and data
- …
Setting Up Symlinks
To make these directories accessible to your Statamic application, you’ll create symlinks from your application to the shared directory. The best way to do this is in a deployment script.
Create a .webslice/build.sh file in your repository:
#!/bin/bash
# Create shared directories if they don't existmkdir -p /mnt/data/website/shared/assetsmkdir -p /mnt/data/website/shared/formsmkdir -p /mnt/data/website/shared/glide-cachemkdir -p /mnt/data/website/shared/logsmkdir -p /mnt/data/website/shared/users
# Remove existing directories/links from the buildrm -rf storage/app/formsrm -rf storage/app/gliderm -rf storage/logsrm -rf public/assets/images
# Create symlinks to persistent storageln -sf /mnt/data/website/shared/forms storage/app/formsln -sf /mnt/data/website/shared/glide-cache storage/app/glideln -sf /mnt/data/website/shared/logs storage/logsln -sf /mnt/data/website/shared/assets/images public/assets/imagesln -sf /mnt/data/website/shared/users users
echo "✓ Symlinks created successfully"Make the script executable:
chmod +x .webslice/deploy.shThis script runs automatically during deployment and ensures your persistent data is properly linked.
Asset Container Configuration
Update your asset container configuration to use the symlinked directory. In content/assets/assets.yaml (or wherever your asset container is configured):
title: Assetsdisk: assetsallow_uploads: trueallow_downloading: trueallow_renaming: trueallow_moving: trueThen ensure your config/filesystems.php has the assets disk properly configured:
'disks' => [ 'assets' => [ 'driver' => 'local', 'root' => public_path('assets'), 'url' => '/assets', 'visibility' => 'public', ], // ... other disks],Since public/assets is symlinked to /mnt/data/website/shared/assets, all your uploaded assets will persist across deployments.
Cache Warming for Peak Performance
Cache warming is the process of pre-generating your static cache files. This is crucial because:
- The first visitor to a page shouldn’t have to wait for it to be cached
- You want all pages cached before traffic hits your site
- It ensures consistent performance from the moment you deploy
The Release Script
Create a .webslice/release.sh file to warm your cache after each deployment:
#!/bin/bash
echo "Starting cache warming..."
# Clear any existing cache to ensure fresh generationphp artisan cache:clearphp artisan statamic:stache:clearphp artisan statamic:static:clear
# Warm the static cachephp artisan statamic:static:warm --queue
echo "✓ Cache warming initiated"
echo "✓ Release complete"Make it executable:
chmod +x .webslice/release.shThis script runs after your deployment goes live. The --queue flag means the warming happens in the background, so your deployment completes quickly, but your cache gets fully warmed shortly after.
Manual Cache Warming
You can also manually warm your cache at any time using the Statamic CLI:
php artisan statamic:static:warmOr from the Statamic Control Panel, navigate to Utilities → Static Caching and click “Warm Cache”.
Forms and Submissions
If you’re using Statamic’s built-in forms, you need to ensure submissions are stored in persistent storage.
In your config/statamic/forms.php:
return [ 'default' => 'file',
'drivers' => [ 'file' => [ 'storage' => 'forms', ], ],];And in config/filesystems.php, add a forms disk:
'disks' => [ 'forms' => [ 'driver' => 'local', 'root' => storage_path('app/forms'), ], // ... other disks],Since we symlinked storage/app/forms to /mnt/data/website/shared/forms in our deploy script, all form submissions will be preserved across deployments.
Image Manipulation (Glide)
Statamic uses Glide for on-the-fly image manipulation. To prevent regenerating these cached images on every deployment:
In your config/statamic/assets.php:
return [ 'image_manipulation' => [ 'driver' => 'gd', // or 'imagick' if available
'cache' => true,
'cache_path' => storage_path('app/glide'),
'presets' => [ // Your image presets ], ],];The storage/app/glide directory is symlinked to /mnt/data/website/shared/glide-cache, so transformed images persist across deployments.
Git Ignore Configuration
Since we’re storing certain directories in persistent storage, you should ensure they’re in your .gitignore:
/vendor/node_modules.env.DS_Store
# Persistent storage directories (handled via symlinks)/public/assets/*!/public/assets/.gitkeep/storage/app/forms/storage/app/glide/storage/logs/*!/storage/logs/.gitkeep/users/*!/users/.gitkeep
# Statamic caches/storage/statamic/*!/storage/statamic/.gitkeepYou can include .gitkeep files to maintain the directory structure in git without committing the contents.
Deployment Checklist
When deploying your Statamic site to Webslice Serverless, follow these steps:
-
Configure static caching in
config/statamic/static_caching.phpwith thefullstrategy -
Create deployment script at
.webslice/deploy.shto set up symlinks to/mnt/data/website/shared -
Create release script at
.webslice/release.shto warm your static cache -
Make scripts executable with
chmod +x .webslice/deploy.sh .webslice/release.sh -
Update asset containers to use the symlinked directories
-
Configure forms to store in persistent storage if using Statamic forms
-
Set up Glide cache in persistent storage for image transformations
-
Update .gitignore to exclude symlinked directories
-
Test locally to ensure symlinks work and cache warms correctly
-
Deploy and monitor the first deployment to ensure cache warming completes
Performance Tips
Maximize Static Caching
The more pages you can statically cache, the better your performance and lower your costs. Consider:
- Caching all public-facing pages
- Using AJAX for dynamic elements on otherwise static pages
- Leveraging the
nocachetag for small dynamic sections within cached pages
Example using the nocache tag:
{{ nocache }} <p>You are visitor number {{ visits }} to this page</p>{{ /nocache }}
<article> <!-- Rest of your cached content --></article>Optimize Assets
Since serverless environments bill by execution time:
- Use responsive images to serve appropriately-sized files
- Implement lazy loading for images below the fold
- Consider using a CDN for assets (though static caching helps significantly)
Monitor Cache Hit Rates
Keep an eye on how well your static cache is performing. You can add custom logging to track cache hits vs. misses and optimize accordingly.
Troubleshooting
Cache Not Warming
If your static cache isn’t warming:
- Check that
.webslice/release.shis executable - Review deployment logs for errors during the release phase
- Try manually warming:
php artisan statamic:static:warm - Check that your routes are discoverable (Statamic crawls from the homepage)
Files Not Persisting
If uploads or form submissions aren’t persisting:
- Verify symlinks are pointing to
/mnt/data/website/shared/* - Check file permissions:
ls -la /mnt/data/website/shared/ - Ensure directories exist before symlinking in your deploy script
Advanced Configuration
Then in your environment variables:
```bash title=".env.production"STATAMIC_STATIC_CACHING_STRATEGY=fullSTATAMIC_WARM_CONCURRENCY=50STATAMIC_STATIC_CACHING_STRATEGY=halfSTATAMIC_WARM_CONCURRENCY=10Custom Cache Warming
For large sites, you might want more control over cache warming. Create a custom command:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;use Statamic\Facades\Entry;
class WarmStaticCacheSelectively extends Command{ protected $signature = 'custom:warm-cache';
protected $description = 'Warm static cache for high-priority pages first';
public function handle() { $this->info('Warming high-priority pages...');
// Warm homepage and main pages first $priorityUrls = ['/', '/blog', '/about', '/contact'];
foreach ($priorityUrls as $url) { \Artisan::call('statamic:static:warm', [ '--url' => $url, ]); }
$this->info('High-priority pages warmed.');
// Then warm all blog posts $this->info('Warming blog posts...');
Entry::query() ->where('collection', 'blog') ->get() ->each(function ($entry) { \Artisan::call('statamic:static:warm', [ '--url' => $entry->url(), ]); });
$this->info('Cache warming complete!'); }}Then call this from your .webslice/release.sh:
#!/bin/bash
echo "Starting selective cache warming..."
php artisan custom:warm-cache
echo "✓ Release complete"Conclusion
With proper configuration, Statamic runs beautifully on Webslice Serverless. The combination of:
- Static caching for performance
- Persistent storage for user data
- Atomic deployments for reliability
- Cache warming for consistent speed
…gives you a fast, cost-effective, and robust hosting solution for your Statamic sites.
The key is embracing the serverless model: keep your application code ephemeral and stateless, store persistent data in /mnt/data/website/shared, and leverage static caching to minimize PHP execution. Follow these patterns, and you’ll have a Statamic site that’s both performant and economical to run.