> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frankenpress.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How the four * repos fit together

FrankenPress is four repos that compose into one WordPress deployment:

```mermaid theme={null}
flowchart TD
    charts["<b>charts</b><br/>Helm chart"]
    template["<b>site-template</b><br/>Bedrock-layout WP site<br/>(builds immutable image)"]
    runtime["<b>runtime</b><br/>Caddy + FrankenPHP + Souin<br/>base container"]
    mu["<b>mu-plugin</b><br/>S3UploadsBootstrap + SouinInvalidator<br/>SiteHealth + SMTPMailer"]

    charts -->|deploys| template
    template -->|FROM| runtime
    runtime -->|bakes at build time| mu
    template -->|composer-installs| mu
```

## The four repos

<CardGroup cols={2}>
  <Card title="runtime" icon="cube" href="/components/runtime">
    Container image: Caddy + FrankenPHP + Souin compiled in. Published as
    `ghcr.io/frankenpress/runtime:php8.3`.
  </Card>

  <Card title="mu-plugin" icon="puzzle-piece" href="/components/mu-plugin">
    Slim must-use plugin (4 components): S3 uploads bootstrap, Souin cache
    invalidator, Site Health overrides, opt-in SMTP mailer. Composer-installable;
    baked into `runtime` by default.
  </Card>

  <Card title="site-template" icon="file-code" href="/components/site-template">
    GitHub template repo. Bedrock layout; composer.json with sensible
    minimal deps. Builds your site image on `git push --tags`.
  </Card>

  <Card title="charts" icon="ship" href="/components/charts">
    Helm chart `site`. Bitnami-style; bundles MariaDB + Redis + MinIO
    for instant `kind` deploys.
  </Card>
</CardGroup>

## Request flow

```mermaid theme={null}
flowchart LR
    client(["client"])
    caddy["Caddy"]
    souin{{"Souin<br/>HTTP cache"}}
    fphp["FrankenPHP worker<br/>(loads WP in-process,<br/>no PHP-FPM)"]
    mu["mu-plugin"]
    s3[(S3)]
    redis[(Redis)]

    client --> caddy --> souin
    souin -->|HIT| client
    souin -->|MISS| fphp
    fphp --> mu
    mu -->|S3UploadsBootstrap| s3
    mu -->|SouinInvalidator on save_post| redis
```

Souin caches GET responses in Redis. On `save_post`,
`SouinInvalidator` connects directly to Redis and `DEL`s the relevant
keys (Souin's documented HTTP-level invalidation APIs are broken in
cache-handler v0.16.0 — see
[`PHASE-0.md`](https://github.com/frankenpress/runtime/blob/main/PHASE-0.md)
for the investigation).

## Image promotion

```mermaid theme={null}
flowchart LR
    tag["git tag v1.0.0<br/>(in site-template fork)"]
    ci["GHA build.yml<br/>composer install →<br/>docker build →<br/>push to GHCR"]
    ghcr[("ghcr.io/owner/site:v1.0.0")]
    helm["helm upgrade<br/>--set image.tag=v1.0.0"]

    tag --> ci --> ghcr --> helm
```

Each tag produces an **immutable** site image (WP core + plugins + your
custom code baked in). Promoting between environments is a single
`helm upgrade` with a different image tag — no separate code-vs-config
to track.

This composes cleanly with image-promotion tooling like
[Kargo](https://kargo.akuity.io/) or
[Argo Rollouts](https://argoproj.github.io/argo-rollouts/) but doesn't
mandate them. The chart renders a plain `Deployment`; consumers wrap
with whatever orchestration they prefer.

## What stays out

* **No WooCommerce / Yoast / theme picks** in `site-template`. Add what you need via `composer require wpackagist-plugin/<slug>`.
* **No GitOps controller**. The chart renders k8s primitives; you bring your own Argo CD / Flux / Kargo.
* **No multi-cluster federation**. One namespace = one site (use multiple Helm releases for multiple sites in one cluster).
* **No admin-installable plugins/themes/core updates**. The image is the source of truth; the lockdown is hard-coded.

## Production swap matrix

| Default (dev / kind)         | Production                                                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `bitnami/mariadb` subchart   | [MariaDB Operator](https://github.com/mariadb-operator/mariadb-operator)                                                                   |
| `bitnami/redis` subchart     | [DragonflyDB Operator](https://github.com/dragonflydb/dragonfly-operator) (same RESP protocol, dramatically better single-node throughput) |
| `bitnami/minio` subchart     | AWS S3 / Cloudflare R2 / GCS XML                                                                                                           |
| auto-generated WP keys+salts | [External Secrets Operator](https://external-secrets.io/) → cloud secret manager                                                           |

Full production walkthrough: [Operations → Production topology](/operations/production).
