site-template,
let it self-customise, push your own image, and deploy that.
We’ll call your new repo mysite throughout — substitute whatever
name you actually pick (my-blog, acme-marketing, etc.). Same for
<owner> — your GitHub account or organisation.
Prerequisites
Required tools
Required tools
- GitHub account with permission to create public repos and packages
- Docker Desktop or OrbStack (macOS), or Docker Engine on Linux
git,make,composergh(GitHub CLI) — optional, but the docs use it for tersenesskind+kubectl+helm≥ v3.8 — only needed for the cluster step
What gets created on your account
What gets created on your account
- A new repo at
github.com/<your-account>/<your-site>(public by default — flip to private if you prefer; cluster-side pulls of a private GHCR package need credentials, e.g. node-level containerd auth on Talos or a per-namespaceimagePullSecret) - A GHCR package at
ghcr.io/<your-account>/<your-site>— built and tagged automatically by CI
Create your site repo
GitHub gives you two ways to derive a new repo from
Whichever you pick, you’ll end up with a new repo at
site-template. Pick whichever matches how closely you want to
track upstream.- Use this template (recommended)
- Fork
Click Use this template
on
site-template. Pick an owner and the name mysite
(or whatever you prefer).- Pros. Clean new repo without the template’s full git history. No “forked from” badge in the GitHub UI. You explicitly choose which upstream changes to pull in by cherry-picking — easier to keep your repo’s history representative of your site rather than the template’s churn.
-
Cons. No “Sync fork” button. To pull upstream improvements
(CI tweaks, lockdown changes, etc.) you add the template as
a remote and cherry-pick:
github.com/<owner>/mysite.Within ~30 seconds GitHub Actions runs the template-cleanup
workflow on your new repo. It does three things:- Substitutes the upstream-hardcoded fields:
composer.json:name,description,homepage,support.issues,support.sourceDockerfile:org.opencontainers.image.sourcelabel
- Removes the cleanup workflow itself (one-shot).
- Triggers
build.ymlto publish the first image.
main: the original template snapshot
and chore: initialize from site-template. Watch progress with:After ~2 minutes,
ghcr.io/<owner>/mysite:latest is pullable
and the workflows tab shows green template-cleanup + build runs.Clone and run locally
fp init is a one-command onboarding helper — it scaffolds .env
from .env.example, runs composer install via docker, brings
the stack up (docker compose up -d --wait), installs WordPress
with sensible local defaults, and applies the latest committed
snapshot (if any). Re-run it after docker compose down -v to
recover from a wiped local stack.Open http://localhost:8080/wp/wp-admin/ and log in
(admin / admin by default; override via [init] in
frankenpress.toml).Lower-level alternative if you’d rather drive it manually:
make wp runs wp-cli in the site container with
--allow-root --path=/app/web/wp (WordPress core lives under
web/wp/ per the Bedrock layout — wp-cli won’t find it
otherwise). Pass your sub-command + flags through ARGS="…".Local Docker Compose is the only place you need to install
WordPress manually (or via
fp init). When you deploy via the
Helm chart (the next steps), the chart runs wp core install
automatically as a post-install hook Job — see charts →
First install.The “Update WordPress” / “Update Plugins” / “Update Themes”
buttons should be absent. The lockdown is hard-coded in
config/application.php — see site-template → Lockdown.http://localhost:9001 (credentials minioadmin / minioadmin).Cut a release
The template’s Watch the build:
build.yml publishes images on every push to main
(:latest + :<short-sha>) and on every v*.*.* tag (:vX.Y.Z
additionally). Tag your first release:Three image tags now exist on
ghcr.io/<owner>/mysite::latest(moves on every main push):<short-sha>(immutable per commit):v0.1.0(immutable per tag — use this in production)
Deploy to a cluster
Same The chart runs Open
site chart as the Quickstart, pointed at
your image:--set site.url=http://localhost:8080 matches the port-forward
URL below; --set site.env=development keeps FORCE_SSL_ADMIN=false
so /wp/wp-admin/ doesn’t 302 to a https:// URL the port-forward
isn’t serving. See Quickstart for the full
explanation. For a real deploy, drop both overrides and set
site.url to your public HTTPS URL.wp core install automatically as a post-install
hook Job — see charts → First install
for the admin credentials, bring-your-own-Secret, and rotation
options.Port-forward and log in:http://localhost:8080/wp/wp-admin/ and log in as admin.What’s next
You’ve gotmysite building, deployed, and serving. The natural next
step is making it yours — adding plugins, picking a theme, swapping
defaults.
Customizing your site
Add and remove plugins and themes the FrankenPress way — composer at build time, immutable image tag, GitOps deploy.
Production topology
Replace bundled subcharts with operator-managed databases + AWS S3.
All env vars
Every
FP_* and WP_* variable the platform reads, with defaults.Upgrade flow
git tag → CI → image build → helm upgrade --set image.tag=... per environment.