How to Self-Host October CMS with Docker Compose
What Is October CMS?
October CMS is a self-hosted content management system built on the Laravel PHP framework. It targets developers who want Laravel’s power with a clean CMS layer on top — backend admin panel, drag-and-drop page builder, plugin marketplace, and a content scaffolding system called Tailor. Think of it as the middle ground between raw Laravel and WordPress: cleaner architecture than WordPress, more batteries-included than a bare framework. Official site.
Licensing note: October CMS uses a proprietary EULA, not an open-source license. The first year is free; ongoing updates and Marketplace access require a paid license. If you need a fully open-source CMS, consider Ghost, WordPress, or Wagtail.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 1 GB of free disk space
- 1 GB of RAM minimum (2 GB recommended)
- PHP 8.2+ and Composer (for initial project creation)
- A domain name (optional, for remote access)
Docker Compose Configuration
First, create the October CMS project using Composer:
composer create-project october/october ~/october-cms
cd ~/october-cms
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 pdo_mysql gd zip simplexml mbstring opcache \
&& a2enmod rewrite \
&& rm -rf /var/lib/apt/lists/*
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/themes
EXPOSE 80
Create docker-compose.yml:
services:
app:
build: .
container_name: october-cms
ports:
- "8080:80"
volumes:
- october_storage:/var/www/html/storage
- october_plugins:/var/www/html/plugins
- october_themes:/var/www/html/themes
environment:
- APP_ENV=production
- APP_DEBUG=false
- APP_URL=http://localhost:8080
- APP_KEY=base64:generate-this-with-artisan
- DB_CONNECTION=mysql
- DB_HOST=october-db
- DB_PORT=3306
- DB_DATABASE=october
- DB_USERNAME=october
- DB_PASSWORD=changeme
- CACHE_STORE=redis
- SESSION_DRIVER=redis
- REDIS_HOST=october-redis
depends_on:
october-db:
condition: service_healthy
october-redis:
condition: service_healthy
restart: unless-stopped
october-db:
image: mariadb:10.11
container_name: october-db
volumes:
- october_dbdata:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=changeme-root
- MYSQL_DATABASE=october
- MYSQL_USER=october
- MYSQL_PASSWORD=changeme
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
october-redis:
image: redis:7-alpine
container_name: october-redis
volumes:
- october_redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
october_storage:
october_plugins:
october_themes:
october_dbdata:
october_redis:
Generate an application key and run migrations:
docker compose build
docker compose up -d
docker compose exec app php artisan key:generate
docker compose exec app php artisan october:migrate
Initial Setup
- Open
http://your-server-ip:8080/adminin your browser - Create the admin account during the first-run setup wizard
- Configure your site name, timezone, and default locale
- Install plugins from the Marketplace through the backend admin panel
- Choose and activate a frontend theme
Configuration
| Setting | Environment Variable | Description |
|---|---|---|
| Database | DB_CONNECTION | mysql, pgsql, or sqlite |
| Cache | CACHE_STORE | file, redis, database, or memcached |
| Sessions | SESSION_DRIVER | file, redis, database, or cookie |
| Admin URL | BACKEND_URI | Admin panel path (default: /admin) |
| Debug mode | APP_DEBUG | Set false in production |
| Site URL | APP_URL | Full URL including protocol |
Tailor Content Scaffolding
Tailor lets you define custom content types without writing code. Create blueprint YAML files in app/blueprints/:
handle: Blog\Post
type: entry
name: Blog Post
fields:
title:
label: Title
type: text
content:
label: Content
type: richeditor
featured_image:
label: Featured Image
type: mediafinder
mode: image
Reverse Proxy
Example Nginx Proxy Manager configuration:
- Scheme:
http - Forward Hostname:
october-cms - Forward Port:
80
See Reverse Proxy Setup for full configuration guides.
Backup
Back up these volumes:
october_dbdata— MariaDB database with all content, users, and settingsoctober_storage— uploaded media, cache, logsoctober_plugins— installed pluginsoctober_themes— installed themes
See Backup Strategy for automated approaches.
Troubleshooting
White Screen / 500 Error After Deployment
Symptom: Blank page or server error on first visit.
Fix: Check permissions on the storage/ directory — it must be writable by the web server: docker compose exec app chown -R www-data:www-data storage. Also verify APP_KEY is set — run php artisan key:generate if needed.
Plugin Installation Fails
Symptom: Marketplace plugins won’t install from the admin panel.
Fix: Ensure the container has outbound internet access. Check that the plugins/ directory is writable. For air-gapped environments, install plugins via Composer: composer require author/plugin-name.
Database Migration Errors
Symptom: october:migrate fails with table errors.
Fix: Ensure the database is fully initialized before running migrations. Check the health of october-db with docker compose ps. For fresh installs, drop and recreate: docker compose exec app php artisan october:migrate --seed.
Resource Requirements
- RAM: ~200 MB idle, ~500 MB under load
- CPU: Low-Medium — Laravel applications are CPU-efficient
- Disk: ~100 MB for core application, plus media uploads
Verdict
October CMS is a polished Laravel-based CMS with a clean architecture and a mature plugin ecosystem. The Tailor content scaffolding system is genuinely useful for building custom content types without plugins. The main drawback is licensing — it’s not open source, and ongoing updates require a paid license after the first year. For a fully open-source Laravel-based CMS, Wagtail (Django, not Laravel) or Ghost are better choices. For PHP specifically, WordPress has a vastly larger ecosystem, while October CMS offers a much cleaner codebase. Choose October CMS if you’re a Laravel developer who wants a familiar framework with CMS capabilities built in.
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