How to Self-Host Statamic with Docker Compose
What Is Statamic?
Statamic is a flat-file CMS built on Laravel that stores content as YAML and Markdown files instead of a database. This makes your entire site — content, configuration, and structure — version-controllable with Git. It features a polished Vue.js control panel with 40+ fieldtypes, live preview, and a flexible content modeling system. Statamic can also run in headless mode with REST API and GraphQL endpoints (Pro feature). Official site.
Licensing note: Statamic Core is free (limited to 1 admin user, 1 form). Statamic Pro costs $275/site (one year of updates, $65/year renewal) and adds unlimited users, REST API, GraphQL, multi-site, revisions, and Git integration. The source code is visible on GitHub but uses a commercial license, not an open-source license.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 500 MB of free disk space
- 512 MB of RAM minimum (1 GB recommended)
- PHP 8.2+ and Composer (for initial project creation)
- A domain name (optional, for remote access)
Docker Compose Configuration
First, create a new Statamic project:
composer create-project statamic/statamic ~/statamic-site
cd ~/statamic-site
Create a Dockerfile in the project root:
FROM php:8.3-apache
RUN apt-get update && apt-get install -y \
libpng-dev libjpeg-dev libfreetype6-dev \
libzip-dev libxml2-dev unzip git \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install gd zip mbstring opcache exif bcmath \
&& a2enmod rewrite \
&& rm -rf /var/lib/apt/lists/*
# Configure Apache document root
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' \
/etc/apache2/sites-available/*.conf \
/etc/apache2/apache2.conf
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader \
&& chown -R www-data:www-data /var/www/html/storage \
&& chown -R www-data:www-data /var/www/html/content \
&& chown -R www-data:www-data /var/www/html/public
EXPOSE 80
Create docker-compose.yml:
services:
statamic:
build: .
container_name: statamic
ports:
- "8080:80"
volumes:
- ./content:/var/www/html/content
- ./users:/var/www/html/users
- statamic_storage:/var/www/html/storage
- ./public/assets:/var/www/html/public/assets
environment:
- APP_ENV=production
- APP_DEBUG=false
- APP_URL=http://localhost:8080
- APP_KEY=base64:generate-this-with-artisan
- STATAMIC_STACHE_WATCHER=true
- STATAMIC_STATIC_CACHING_STRATEGY=null
restart: unless-stopped
volumes:
statamic_storage:
Generate an application key and create the first user:
docker compose build
docker compose up -d
docker compose exec statamic php artisan key:generate
docker compose exec statamic php please make:user
Initial Setup
- Run
docker compose exec statamic php please make:userto create your admin account - Open
http://your-server-ip:8080/cpto access the control panel - Log in with the credentials you just created
- Start creating collections, pages, and entries through the control panel
- Content is saved as YAML/Markdown files in the
content/directory
Configuration
| Setting | Environment Variable | Description |
|---|---|---|
| Site URL | APP_URL | Full URL including protocol |
| Debug mode | APP_DEBUG | Set false in production |
| File watcher | STATAMIC_STACHE_WATCHER | Auto-detect content file changes (true/false) |
| Static caching | STATAMIC_STATIC_CACHING_STRATEGY | null, half, or full for static page caching |
| License key | STATAMIC_LICENSE_KEY | Required for Pro features in production |
Content Storage
Statamic stores all content as flat files:
| Directory | Contents |
|---|---|
content/collections/ | Collection entries (blog posts, pages, etc.) |
content/globals/ | Global variable sets |
content/navigation/ | Navigation menus |
content/taxonomies/ | Taxonomy terms |
users/ | User accounts (YAML files) |
resources/blueprints/ | Content type definitions |
resources/fieldsets/ | Reusable field groups |
Because everything is in flat files, you can edit content directly in your text editor, commit changes to Git, and deploy via CI/CD — no database migrations needed.
Optional Database Backend
For larger sites or when you need SQL queries, Statamic supports database storage via Laravel’s Eloquent driver:
# In docker-compose.yml, add a database service and set:
# DB_CONNECTION=mysql
# DB_HOST=statamic-db
# ...standard Laravel database env vars
Reverse Proxy
Example Nginx Proxy Manager configuration:
- Scheme:
http - Forward Hostname:
statamic - Forward Port:
80
See Reverse Proxy Setup for full configuration guides.
Backup
The flat-file architecture makes backup straightforward:
content/— all site content (YAML/Markdown files). Commit to Git for version history.users/— user accountspublic/assets/— uploaded media filesstatamic_storagevolume — cache, logs, sessions
With Git-based content, your entire site is backed up every time you commit. For media files, use a separate backup strategy.
See Backup Strategy for automated approaches.
Troubleshooting
Control Panel Returns 404
Symptom: Visiting /cp returns a 404 error.
Fix: Ensure Apache’s mod_rewrite is enabled and the document root points to /var/www/html/public (not /var/www/html). The Dockerfile above handles this, but verify with docker compose exec statamic apache2ctl -M | grep rewrite.
Content Changes Not Reflecting
Symptom: Edits to YAML files don’t appear on the site.
Fix: Set STATAMIC_STACHE_WATCHER=true to enable file watching. If changes still don’t appear, clear the Stache cache: docker compose exec statamic php artisan stache:clear.
Permission Errors When Saving Content
Symptom: Control panel shows “Permission denied” when saving entries.
Fix: Ensure the web server user owns the content and storage directories: docker compose exec statamic chown -R www-data:www-data content storage users.
Asset Uploads Failing
Symptom: Uploading images or files through the control panel fails.
Fix: Check that public/assets/ is writable and the volume mount is correct. Verify the asset container is configured in config/statamic/assets.php.
Resource Requirements
- RAM: ~100 MB idle, ~300 MB under load
- CPU: Low — flat-file reads are fast, no database queries
- Disk: ~50 MB for application, plus content and media uploads
Verdict
Statamic is the best flat-file CMS available if you value Git-based content workflows. The control panel is polished, content modeling is flexible, and the Laravel foundation means you can extend it with any Laravel package. The flat-file approach means exceptional performance and dead-simple backups. The main drawback is cost — Pro features ($275/site) are needed for multi-user setups, APIs, and revisions. For a free, database-backed CMS with similar quality, Ghost is the strongest alternative. For a fully open-source flat-file option, Grav is worth considering, though its control panel is less polished.
Frequently Asked Questions
Is Statamic free to use?
Statamic Core is free but limited to 1 admin user and 1 form. Statamic Pro ($275/site with $65/year renewal) adds unlimited users, REST API, GraphQL, multi-site support, revisions, and Git integration. The source code is publicly visible on GitHub but uses a commercial license, not an open-source license.
How does Statamic compare to WordPress?
Statamic is a flat-file CMS that stores content as YAML/Markdown files — no database needed, everything is Git-versionable. WordPress uses MySQL and has a massive plugin ecosystem. Statamic is better for developer-friendly workflows and performance; WordPress is better for non-technical users and extensive third-party integrations.
Can Statamic work as a headless CMS?
Yes, with the Pro license. Statamic Pro includes REST API and GraphQL endpoints, allowing you to use it as a headless CMS that serves content to a separate frontend built with React, Vue, Next.js, or any other framework.
Does Statamic need a database?
No. By default, Statamic stores all content as flat YAML and Markdown files. For larger sites needing SQL queries, it optionally supports database storage via Laravel’s Eloquent driver (MySQL, PostgreSQL, SQLite). Most sites work well with flat files.
Can I use Statamic with Git-based deployments?
Yes — this is one of Statamic’s core strengths. Since content is stored as flat files, you can commit everything to Git, review changes in pull requests, and deploy via CI/CD pipelines. The Pro license adds a built-in Git integration that auto-commits content changes from the control panel.
How does Statamic compare to Ghost?
Statamic is a general-purpose CMS with flexible content modeling (40+ fieldtypes, custom collections, taxonomies). Ghost is focused on publishing and newsletters with a simpler content model. Ghost is free and open-source; Statamic Pro is paid. Choose Statamic for complex content structures, Ghost for straightforward blogging and newsletter publishing.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments