generated from bisco/codex-bootstrap
feat: use host bind mounts for persistent data
This commit is contained in:
@@ -18,8 +18,9 @@ sanitized theme modifications, while a must-use plugin owns Shows and Gallery cu
|
||||
post types so structured content is not lost when changing themes.
|
||||
|
||||
NGINX is the only public entry point. WP-CLI provides an idempotent opt-in bootstrap;
|
||||
Certbot provides opt-in direct TLS. Docker networks isolate the database and functional
|
||||
tests use separate volumes.
|
||||
Certbot provides opt-in direct TLS. Docker networks isolate the database. Runtime state
|
||||
uses host-based bind mounts with a preparation script for ownership/mode, while
|
||||
functional tests use separate Docker volumes.
|
||||
|
||||
## Consequences
|
||||
|
||||
@@ -48,11 +49,12 @@ headers, and fail-closed TLS. Admin MFA and allowlisting remain external control
|
||||
## Operational impact
|
||||
|
||||
Database and WordPress files are coordinated state and must be backed up together.
|
||||
Host bind-mount paths must be permissioned for the image users before startup.
|
||||
Operators must monitor upstream security releases and rebuild pinned images. SMTP and
|
||||
off-host storage are not part of this minimal base.
|
||||
|
||||
## Rollback
|
||||
|
||||
Revert the implementation commit and rebuild. Preserve WordPress, database, and
|
||||
certificate volumes unless data deletion is intentional. Restore data only from a
|
||||
verified coordinated backup.
|
||||
Revert the implementation commit and rebuild. Preserve the configured WordPress,
|
||||
database, and certificate host directories unless data deletion is intentional. Restore
|
||||
data only from a verified coordinated backup.
|
||||
|
||||
@@ -16,8 +16,9 @@ activates the theme, configures the site, and creates realistic demo content. Ce
|
||||
another optional service, enabled only for direct deployments. It shares challenge and
|
||||
certificate volumes with NGINX but has no container-control access.
|
||||
|
||||
Persistent state lives in `db_data`, `wordpress_data`, and the certificate volumes.
|
||||
Functional tests replace the first two with isolated test volumes and reach NGINX via
|
||||
an internal `azionelab.org` network alias.
|
||||
Persistent state lives in host-based bind mounts configured by `DB_DATA_PATH`,
|
||||
`WORDPRESS_DATA_PATH`, `LETSENCRYPT_DATA_PATH`, and `CERTBOT_CHALLENGES_PATH`.
|
||||
Functional tests replace the database and WordPress mounts with isolated Docker test
|
||||
volumes and reach NGINX via an internal `azionelab.org` network alias.
|
||||
|
||||
See [ADR-0001](adr/0001-wordpress-single-page.md).
|
||||
|
||||
+18
-4
@@ -12,6 +12,19 @@ docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh
|
||||
NGINX binds to loopback ports 8080/8443. WordPress and MariaDB remain private. The
|
||||
bootstrap is safe to rerun and does not duplicate demo records.
|
||||
|
||||
The default persistent paths are host-based bind mounts under `./runtime`. Before the
|
||||
first start, run:
|
||||
|
||||
```bash
|
||||
./scripts/prepare-host-volumes.sh
|
||||
```
|
||||
|
||||
The script reads `.env`, creates the configured paths, and applies the expected
|
||||
container ownership. For Linux hosts this avoids the common problem where Docker
|
||||
creates missing bind-mount directories as `root:root` and WordPress or MariaDB later
|
||||
cannot write to them. If a platform uses different image UIDs/GIDs, override
|
||||
`MARIADB_VOLUME_UID/GID`, `WORDPRESS_VOLUME_UID/GID`, or `CERTBOT_VOLUME_UID/GID`.
|
||||
|
||||
## Production
|
||||
|
||||
Required controls:
|
||||
@@ -35,7 +48,8 @@ behavior, removing only the staging certificate volume when necessary.
|
||||
|
||||
## State and rollback
|
||||
|
||||
Database and WordPress file volumes must be backed up together. Code rollback is a
|
||||
container rebuild from a prior commit and does not require deleting volumes. Never use
|
||||
`docker compose down --volumes` where content must survive. Test database restoration
|
||||
in a disposable environment before any production restore.
|
||||
Database and WordPress file directories must be backed up together. Code rollback is a
|
||||
container rebuild from a prior commit and does not require deleting host data
|
||||
directories. Never delete the paths configured by `DB_DATA_PATH`, `WORDPRESS_DATA_PATH`,
|
||||
or `LETSENCRYPT_DATA_PATH` where content/certificates must survive. Test database
|
||||
restoration in a disposable environment before any production restore.
|
||||
|
||||
+10
-4
@@ -6,6 +6,7 @@
|
||||
docker compose up --build -d
|
||||
docker compose ps
|
||||
docker compose logs -f proxy wordpress db certbot
|
||||
./scripts/prepare-host-volumes.sh
|
||||
docker compose --profile tools run --rm wp-cli -c 'wp core version'
|
||||
docker compose down
|
||||
```
|
||||
@@ -24,9 +25,11 @@ image rebuilds are the update path.
|
||||
|
||||
## Backup and restore
|
||||
|
||||
Create database and `wordpress_data` backups in one maintenance window. Backups contain
|
||||
credentials, accounts, contact information, and uploaded media; encrypt them, restrict
|
||||
access, set retention, and store copies off-host.
|
||||
Create database and WordPress file backups in one maintenance window. The default host
|
||||
paths are `./runtime/db`, `./runtime/wordpress`, `./runtime/letsencrypt`, and
|
||||
`./runtime/certbot/www`, unless overridden in `.env`. Backups contain credentials,
|
||||
accounts, contact information, and uploaded media; encrypt them, restrict access, set
|
||||
retention, and store copies off-host.
|
||||
|
||||
A restore is destructive. Validate it on isolated volumes, then stop WordPress, restore
|
||||
the database and file volume together, restart, and verify the homepage, media,
|
||||
@@ -34,7 +37,10 @@ the database and file volume together, restart, and verify the homepage, media,
|
||||
|
||||
## Known risks
|
||||
|
||||
- Local named volumes are not backups.
|
||||
- Local host directories are not backups.
|
||||
- A host-based volume may be unreadable by the application if created with the wrong
|
||||
owner or mode; run `./scripts/prepare-host-volumes.sh` after changing paths or image
|
||||
user IDs.
|
||||
- SMTP is not configured; WordPress password-reset email needs an external mail service.
|
||||
- Admin MFA and network allowlisting are deployment concerns and are not bundled.
|
||||
- WordPress plugins expand the attack surface; install only reviewed, maintained,
|
||||
|
||||
+11
-3
@@ -14,10 +14,17 @@
|
||||
|
||||
## Images or theme are missing
|
||||
|
||||
1. Confirm `wordpress_data` is mounted in both WordPress and WP-CLI.
|
||||
1. Confirm `WORDPRESS_DATA_PATH` is mounted in both WordPress and WP-CLI.
|
||||
2. Run `docker compose --profile tools run --rm wp-cli -c 'wp theme status azionelab'`.
|
||||
3. Verify file ownership before changing permissions; never make the tree world-writable.
|
||||
|
||||
## A service cannot write to its volume
|
||||
|
||||
1. Stop the affected service.
|
||||
2. Confirm the relevant `.env` path points to the intended host directory.
|
||||
3. Run `./scripts/prepare-host-volumes.sh`.
|
||||
4. Start the service and inspect logs without printing secret values.
|
||||
|
||||
## Certificate issuance fails
|
||||
|
||||
Verify public DNS, inbound port 80, the operator email, and staging mode. Request a
|
||||
@@ -26,5 +33,6 @@ Avoid repeated production-CA retries while debugging.
|
||||
|
||||
## Rollback
|
||||
|
||||
Revert the deployment commit and rebuild while preserving all named volumes. Restore
|
||||
database/files only for a data rollback and only from a verified coordinated backup.
|
||||
Revert the deployment commit and rebuild while preserving all host data directories.
|
||||
Restore database/files only for a data rollback and only from a verified coordinated
|
||||
backup.
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
- Containers are not privileged and do not use host networking or the Docker socket.
|
||||
WordPress/Apache retains the capabilities needed by the official image internally,
|
||||
but no WordPress port is published.
|
||||
- Persistent state uses host-based bind mounts. Keep those paths outside the public web
|
||||
root, restrict host access, never make them world-writable, and run
|
||||
`./scripts/prepare-host-volumes.sh` when paths or image user IDs change.
|
||||
- WordPress/Apache access logs are disabled to avoid duplicate client metadata and
|
||||
healthcheck noise; NGINX remains the single request log and PHP warnings/errors stay
|
||||
visible.
|
||||
|
||||
+6
-5
@@ -14,11 +14,12 @@ docker compose config --quiet
|
||||
LETSENCRYPT_ENABLED=1 docker compose config --quiet
|
||||
```
|
||||
|
||||
The override replaces normal database and WordPress volumes, maps `azionelab.org` to
|
||||
the internal proxy, and never publishes an extra port. Browser tests cover content and
|
||||
section order, contact actions, mobile overflow/navigation, semantic landmarks, image
|
||||
alternatives, admin routing, security headers, blocked sensitive routes, and unknown
|
||||
virtual hosts.
|
||||
The normal stack uses host-based bind mounts under `./runtime` by default. The test
|
||||
override replaces database and WordPress state with isolated Docker volumes, maps
|
||||
`azionelab.org` to the internal proxy, and never publishes an extra port. Browser tests
|
||||
cover content and section order, contact actions, mobile overflow/navigation, semantic
|
||||
landmarks, image alternatives, admin routing, security headers, blocked sensitive
|
||||
routes, and unknown virtual hosts.
|
||||
|
||||
Subjective visual review and a real-device accessibility audit remain manual release
|
||||
checks.
|
||||
|
||||
Reference in New Issue
Block a user