Commit Graph
2 Commits
Author SHA1 Message Date
Claude a5d57050b3 wordpress: switch to dedicated MariaDB per site (was shared)
Reconsidered after the shared-MariaDB design's real cost became clear:
Kopia's generic backup (services/backup.sh) stops a service's
container to snapshot it, so a shared MariaDB instance would back up
-- and would have to be restored -- as one unit covering every site at
once. Restoring just one site's database to an earlier point meant
restoring the whole shared snapshot to a temporary location first and
manually extracting that site's data back out, not a direct restore.

Each site now gets its own dedicated MariaDB container embedded in its
own docker-compose.yml (same pattern as services/nextcloud.sh) instead
of registering a database on a shared instance:
- Removed _wordpress_ensure_shared_db() and the wordpress-db/
  wordpress_net shared resources entirely.
- Each site's compose file gets a `db` service (container
  <site>-db) on an explicitly-named per-site default network
  (<site>_net), so wp-cli's one-off container reliably joins the
  right network without depending on Docker Compose's implicit
  naming convention.
- DB creation goes through the mariadb image's own MYSQL_DATABASE/
  MYSQL_USER/MYSQL_PASSWORD env vars on first boot (same as
  nextcloud.sh) instead of an imperative `docker exec mysql -e
  "CREATE DATABASE..."` against a shared container.
- Root and site DB passwords are both reused across reruns (read from
  the existing .env), verified via a real update-mode rerun.

Tradeoff, stated in both the script's header comment and the generated
per-site README: more RAM per site (~100-150MB for a full MariaDB
container instead of a slice of one shared instance) in exchange for
independent backup/restore. Data was already fully isolated either way
(separate database + user, always required since WordPress's schema
uses generic table names) -- the shared-vs-dedicated choice was only
ever about the container/process, not the data.

Re-verified end-to-end against the fake docker shim: distinct ports,
distinct dedicated DB containers/networks per site, correct compose/
.env structure, credentials preserved across an update-mode rerun.

docs/vps-sizing-recommendations.md: updated to match -- WordPress
capacity recomputed for dedicated-per-site MariaDB (~580MB headroom at
4 sites, ~976MB at 2, vs. the shared design's ~700MB/~950MB).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBtExJcqxnokyZZKmphdug
2026-08-09 21:23:24 +00:00
Claude a26d1831ee Add services/wordpress.sh — multi-site WordPress with shared MariaDB
New service: self-hosted WordPress, sized for running several
independent sites the way a hosting company would, not just one blog.

- Multi-site from the start: every site requires a name (no unnamed
  "first instance" special case like mattermost's — there's no
  backward-compat reason to special-case one here) and gets its own
  directory/container/port, but all sites share ONE MariaDB container
  (chain-installed on first site, reused by every other one) instead of
  a dedicated database container per site — same resource-sharing idea
  as services/coturn.sh, just scoped to WordPress's own sites rather
  than shared across different services. Each site gets its own
  database + user within that shared instance.
- E-commerce is just WooCommerce, a normal WordPress plugin — no
  separate infrastructure. PHP memory_limit/upload_max_filesize/
  post_max_size are pre-tuned (256M/64M/64M) so a product-catalog
  import doesn't hit default-image limits on the first try.
- wp-cli (official wordpress:cli image, run as a one-off container
  sharing the site's html volume) does the initial WordPress core
  install non-interactively — title, admin account — so there's no
  browser setup wizard to remember per site. Falls back to printing
  the exact manual command if the site wasn't ready in time.
- Auto-scans for a free host port per site (multiple sites can't all
  bind 8090), matching the "auto-scanned free ports for extras" idea
  already used by mattermost's multi-instance support.
- DB and admin passwords are reused across reruns (checked against the
  DB-password-regeneration bug class already fixed elsewhere in this
  repo, e.g. PR #265) — verified via a real update-mode rerun that the
  credential doesn't change.
- setup.sh: is_installed() gets a wordpress case — every site is named
  from the first one on, so there's never a plain $DOCKER_DIR/wordpress
  directory the default case could match against.
- README.md: added to the utilities services table + copiable list per
  CLAUDE.md's three-step rule for new services. Also fixed `coturn`
  being in the homelab row's prose but missing from the copiable list
  block below it — a pre-existing gap from when coturn.sh was merged.

Verified end-to-end via non-interactive dry runs against a fake docker
shim (no live daemon in this environment): 3 sites installed in
sequence get 3 distinct databases, 3 distinct auto-scanned ports, the
shared DB is only set up once, and an update-mode rerun preserves the
existing DB password rather than regenerating it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBtExJcqxnokyZZKmphdug
2026-08-09 20:57:18 +00:00