Octa — A modern WordPress boilerplate built on Bedrock, Sage/Acorn 5, Vite, Tailwind CSS 4 and Alpine.js
| Layer | Technology |
|---|---|
| CMS | WordPress 6.9 (Composer-managed) |
| PHP Framework | Acorn 5 (Laravel-style) |
| Structure | Bedrock |
| Templating | Blade |
| Bundler | Vite 7 |
| CSS | Tailwind CSS 4 |
| JS | Alpine.js 3, TypeScript |
| Docker | MariaDB 11.4, PHP-FPM 8.4, Nginx |
| CI | GitHub Actions |
- PHP >= 8.4
- Node >= 24
- Composer 2
- pnpm
- Docker (optional)
composer install
pnpm installcp .env .env.localEdit .env.local with your database credentials and site URL:
PROJECT_NAME='my-project'
DB_HOST='database'
DB_NAME='database_name'
DB_USER='database_user'
DB_PASSWORD='database_password'
WP_ENV='development'
WP_HOME='http://127.0.0.1:8000'
WP_SITEURL="${WP_HOME}/wp"With Docker:
docker compose up -dThe site is available at http://127.0.0.1:8000.
Without Docker:
Point your web server to the public/ directory and configure your local database, then update .env.local accordingly:
DB_HOST='localhost'pnpm devStarts the Vite dev server with HMR.
app/
├── Providers/ # Service providers (assets, blocks, theme)
└── View/
└── Composers/ # Blade view composers
bedrock/
├── application.php # WordPress bootstrap & config
└── environments/ # Per-environment overrides (development, staging)
config/ # Acorn config (theme, ACF, mail, prettify…)
resources/
├── css/ # Tailwind CSS (app, editor, blocks/)
├── js/ # TypeScript (app, editor)
├── views/ # Blade templates
├── fonts/
└── images/
public/
├── build/ # Vite output (manifest.json)
├── content/ # Plugins, mu-plugins, uploads
└── wp/ # WordPress core (never edit)
helm/ # Kubernetes Helm chart
routes/ # Custom route definitions
| Command | Description |
|---|---|
pnpm dev |
Vite dev server with HMR |
pnpm build |
Production build to public/build/ |
| Command | Description |
|---|---|
pnpm lint |
Lint JS/TS with ESLint |
pnpm lint:fix |
Auto-fix JS/TS lint errors |
composer lint |
Lint PHP with Laravel Pint (PSR-12) |
composer lint:fix |
Auto-fix PHP lint errors |
| Command | Description |
|---|---|
pnpm translate |
Generate .pot and update .po files |
pnpm translate:compile |
Compile .mo and JSON translations |
| Command | Description |
|---|---|
docker compose up -d |
Start stack (MariaDB + PHP + Nginx) |
docker compose down |
Stop stack |
Vite compiles resources/ to public/build/. The manifest is handled by AssetsServiceProvider. Path aliases available:
@scripts→resources/js@styles→resources/css@fonts→resources/fonts@images→resources/images
Theme supports, menus, and image sizes are configured in config/theme.php and registered by ThemeServiceProvider.
theme.json is auto-generated by @roots/vite-plugin from your Tailwind config and the base theme.json file.
Block-specific CSS goes in resources/css/blocks/ and is dynamically enqueued by BlockAssetsServiceProvider.
Custom editor blocks, formats, variations, and plugins are registered from resources/js/editor/.
Environment variables are loaded from .env (and .env.local override) via Dotenv in bedrock/application.php. Per-environment overrides live in bedrock/environments/.
All plugins are managed via Composer (wpackagist-plugin/*) and installed to public/content/plugins/. Never install plugins manually.
PSR-12 enforced by Laravel Pint — see pint.json.
ESLint v9 with flat config — see eslint.config.js:
- Single quotes, no semicolons
- 2-space indent
- Trailing commas on multiline
.editorconfig ensures consistent formatting across editors (2-space for JS/JSON/YAML, 4-space for PHP).
| Service | Image | Port |
|---|---|---|
| database | mariadb:11.4 | 3306 (internal) |
| wordpress | wodby/wordpress-php:8.4 | — |
| frontend | wodby/nginx | 8000 |
| mailer | mailpit | 1025 / 8025 |
GitHub Actions runs on every PR and push to main:
- PHP: Composer install +
pint --test - Node: pnpm install +
eslint+vite build
The Dockerfile provides a multi-stage production build:
- Node dependencies + Vite build
- Composer install (no-dev)
- Final image based on
inrage/docker-wordpress:8.4-redis
A Helm chart is available in helm/ for Kubernetes deployments.
