Week 1 infrastructure: Docker environments, deploy pipeline, bookstore-core scaffold
Docker Compose environments for dev/staging/production (MariaDB, Redis, Caddy, Action Scheduler cron sidecar), an idempotent deploy script, git-hook-based deploy pipeline, backup/restore scripts, and the bookstore-core plugin stub with WooCommerce HPOS compatibility declared. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# Bookstore
|
||||
|
||||
WordPress + WooCommerce bookstore. Design reference: see `docs/` for the
|
||||
pre-launch plan and the technical design doc (`bookstore-core` schema,
|
||||
interfaces, order state machine — the design doc is the source of truth for
|
||||
*why* this repo is laid out the way it is).
|
||||
|
||||
This week's scope (Week 1 of the 5-week plan): environments, deploy
|
||||
pipeline, and the WooCommerce/HPOS plugin scaffold. Catalog schema, pricing,
|
||||
supplier adapters, and the order state machine are Week 2+ and live under
|
||||
`wp-content/plugins/bookstore-core/includes/`, currently empty.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
docker-compose.yml base services: db, redis, wordpress, cron
|
||||
docker-compose.{dev,staging,production}.yml per-environment overrides (caddy, mailhog)
|
||||
docker/php/ app image: WP core image + wp-cli, composer, redis ext
|
||||
docker/caddy/ one Caddyfile per environment
|
||||
docker/cron/ Action Scheduler driver (system cron has no host to run on in Docker)
|
||||
deploy/deploy.sh idempotent bring-up + WP/WooCommerce config
|
||||
deploy/hooks/post-receive git-server hook: push to `staging`/`main` deploys
|
||||
deploy/backup.sh, restore.sh off-host backup; restore is staging-only, on purpose
|
||||
wp-content/plugins/bookstore-core/ the one plugin that owns business logic
|
||||
wp-content/mu-plugins/ local-mail-catcher.php — routes mail to MailHog outside production
|
||||
```
|
||||
|
||||
Same code runs in every environment; only `.env.<env>` and which
|
||||
`docker-compose.<env>.yml` you layer in differ (design doc §01).
|
||||
|
||||
## Local development
|
||||
|
||||
```
|
||||
cp .env.example .env.dev # fill in DB_PASSWORD etc.; localhost values are fine
|
||||
make up ENV=dev
|
||||
make deploy ENV=dev # installs WP, WooCommerce, activates bookstore-core, enables HPOS
|
||||
```
|
||||
|
||||
Site is at `http://localhost:8080`. `make wp ENV=dev ARGS="plugin list"` runs
|
||||
any wp-cli command; `make logs ENV=dev` tails everything; `make shell ENV=dev`
|
||||
drops into the app container.
|
||||
|
||||
## Staging (this is what goes on your Docker server)
|
||||
|
||||
```
|
||||
cp .env.example .env.staging
|
||||
# fill in SITE_DOMAIN, SITE_URL, DB_*, and:
|
||||
docker run --rm caddy:2-alpine caddy hash-password --plaintext 'pick-a-password'
|
||||
# -> paste result into STAGING_BASIC_AUTH_HASH
|
||||
|
||||
make deploy ENV=staging
|
||||
```
|
||||
|
||||
Staging is `noindex`'d and sits behind HTTP basic auth (Caddyfile.staging)
|
||||
in addition to `blog_public=0` — two independent reasons search engines and
|
||||
random visitors won't see it, per the launch gate. Mail never leaves the
|
||||
box: it's caught by MailHog, viewable at `:8025`.
|
||||
|
||||
### Theme: Blocksy + the Book Store starter site
|
||||
|
||||
`deploy.sh` installs and activates the **Blocksy** theme and the free
|
||||
**Blocksy Companion** plugin from wordpress.org automatically — nothing to
|
||||
do here, in any environment.
|
||||
|
||||
The **Book Store starter site** itself is a paid Companion Pro template
|
||||
(Business plan, $99/year — design doc Appendix A), so it can't be scripted
|
||||
against a public API the way the free theme can. One-time manual step per
|
||||
environment, in wp-admin:
|
||||
|
||||
1. Purchase/retrieve the Blocksy Business license key.
|
||||
2. **Blocksy → General → License** → activate it.
|
||||
3. **Blocksy → Extensions → Starter Sites** (Companion Pro) → import
|
||||
**Book Store**.
|
||||
|
||||
After that, the starter site's content and Customizer settings persist in
|
||||
the database like any other WordPress content — a redeploy or a fresh
|
||||
`deploy.sh` run doesn't touch it or need to repeat it.
|
||||
|
||||
## Deploy pipeline
|
||||
|
||||
This assumes your own bare Git server, not a hosted CI. The mechanism:
|
||||
|
||||
1. A bare repo lives on the server (e.g. `/srv/git/bookstore.git`).
|
||||
2. `deploy/hooks/post-receive` is copied into `<bare-repo>.git/hooks/` and
|
||||
made executable. Edit `DEPLOY_ROOT` at the top of it first.
|
||||
3. Pushing to `staging` checks that branch out into
|
||||
`$DEPLOY_ROOT/staging` and runs `deploy.sh staging`; pushing to `main`
|
||||
deploys `$DEPLOY_ROOT/production` the same way.
|
||||
4. `deploy.sh` is idempotent — it's safe to re-run and safe to be the thing
|
||||
the hook calls on every push.
|
||||
|
||||
You can also just run `./deploy/deploy.sh <env>` by hand from a checked-out
|
||||
copy on the server; the hook is only automation on top of the same script.
|
||||
|
||||
## Backups
|
||||
|
||||
```
|
||||
./deploy/backup.sh staging # or production
|
||||
```
|
||||
|
||||
Dumps the database and archives `wp-content/uploads`, gzips both, and syncs
|
||||
to `$BACKUP_REMOTE` via `rclone` if set (configure `rclone config` on the
|
||||
server first — this repo doesn't manage remote credentials). Before launch,
|
||||
run a real restore drill:
|
||||
|
||||
```
|
||||
./deploy/restore.sh ./backups/production/db-<ts>.sql.gz ./backups/production/uploads-<ts>.tar.gz
|
||||
```
|
||||
|
||||
`restore.sh` only ever targets staging — there's no production argument, so
|
||||
a restore drill can't accidentally overwrite the live site.
|
||||
|
||||
## What's deliberately not here yet
|
||||
|
||||
- Catalog tables, pricing engine, supplier adapters, order state machine —
|
||||
Week 2–4, see the design doc.
|
||||
- A real TLS-terminating public domain — Caddy will auto-provision certs
|
||||
once `SITE_DOMAIN` points at a real host with 80/443 reachable; until
|
||||
then `docker-compose.dev.yml` is the only one that works from
|
||||
`localhost`.
|
||||
- CI test/lint automation — nothing here runs tests yet because there's no
|
||||
application code to test yet.
|
||||
Reference in New Issue
Block a user