Azione!Lab WordPress

A warm, editorial single-page website for the Azione!Lab contemporary theatre workshop. WordPress manages the content, a custom theme owns the visual system, and Docker Compose provides MariaDB, NGINX, optional Let's Encrypt, WP-CLI, and isolated browser tests.

Architecture

  • wordpress/: pinned WordPress 7/PHP 8.3 image, custom theme, and structured-content must-use plugin.
  • db: MariaDB 11.8 LTS, available only on the internal data network.
  • proxy: the only published service; routes azionelab.org to WordPress and applies edge security controls.
  • certbot: optional HTTP-01 certificate issue/renewal service.
  • wp-cli: opt-in bootstrap and maintenance service.
  • tests/functional: Playwright tests running only through the public virtual host.

See architecture and ADR-0001.

Prerequisites

  • Docker Engine with Docker Compose v2.
  • Local ports 8080 and 8443 available.
  • 127.0.0.1 azionelab.org in the local hosts file.

No host PHP, database, Node.js, or WordPress installation is required.

Start locally

cp .env.example .env
./scripts/prepare-host-volumes.sh
docker compose up --build -d
docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh
docker compose ps

Open:

Use the development credentials copied into .env only locally. Change them before sharing the environment.

Persistent data uses host-based bind mounts by default:

  • ./runtime/db for MariaDB;
  • ./runtime/wordpress for WordPress core, uploads, themes, and mu-plugins copied at container startup;
  • ./runtime/letsencrypt for certificates;
  • ./runtime/certbot/www for ACME HTTP-01 challenges.

Run ./scripts/prepare-host-volumes.sh before the first start, especially on Linux hosts. The script reads .env, creates the directories, and assigns the expected container owners (999:999 for MariaDB, 33:33 for WordPress, 0:0 for Certbot). Override the *_DATA_PATH and *_VOLUME_UID/GID variables in .env if your runtime uses different host paths or image user IDs.

Edit content

  • Appearance > Customize: hero, manifesto, laboratory, teacher, lessons, contacts, social links, and footer.
  • Shows: poster, title, excerpt, year, place, and order.
  • Gallery: image, category, caption/title, and order.
  • Settings > General: site name and tagline.

Real uploaded images replace the built-in editorial SVG placeholders. The three participation cards remain intentional theme copy; making them reorderable is a TODO if the workshop later needs more than the current three fixed audiences.

Production configuration

Set WP_ENVIRONMENT_TYPE=production, unique database passwords of at least 16 characters, a strong admin password, the public HTTPS WP_URL, and WORDPRESS_DEBUG=0. Production startup rejects placeholder database credentials. WordPress file editing and web-based theme/plugin/core modification are disabled; deploy updates by rebuilding the pinned image.

When a trusted load balancer owns TLS, keep LETSENCRYPT_ENABLED=0 and set TRUST_PROXY_HEADERS=1 only if NGINX is reachable exclusively from that load balancer and the load balancer overwrites forwarding headers.

For direct exposure, point public DNS at the host, expose ports 80/443, and start with the Let's Encrypt staging CA:

WP_ENVIRONMENT_TYPE=production
WP_URL=https://azionelab.org
LETSENCRYPT_ENABLED=1
LETSENCRYPT_DOMAIN=azionelab.org
LETSENCRYPT_EMAIL=operator@example.org
LETSENCRYPT_STAGING=1
NGINX_BIND_ADDRESS=0.0.0.0
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
TRUST_PROXY_HEADERS=0

Before the first certificate exists, NGINX serves ACME challenges and returns 503 for application traffic. After issuance, HTTP redirects to HTTPS automatically.

Run the real bootstrap without the test override:

docker compose --profile tools run --rm wp-cli /scripts/bootstrap.sh

The docker-compose.test.yml override intentionally uses disposable test volumes; do not use it for production or staging bootstrap commands.

Useful commands

docker compose logs -f proxy wordpress db certbot
docker compose --profile tools run --rm wp-cli -c 'wp plugin list'
docker compose --profile tools run --rm wp-cli -c 'wp core version'

docker compose run --rm --no-deps wordpress php -l /opt/azionelab/theme/functions.php
docker compose run --rm --no-deps wordpress php -l /opt/azionelab/theme/front-page.php
docker compose run --rm --no-deps wordpress php -l /opt/azionelab/azionelab-content.php
docker compose run --rm --no-deps proxy nginx -t
docker compose -f docker-compose.yml -f docker-compose.test.yml up --build -d db wordpress proxy
docker compose -f docker-compose.yml -f docker-compose.test.yml --profile tools run --rm wp-cli /scripts/bootstrap.sh
docker compose -f docker-compose.yml -f docker-compose.test.yml --profile test run --build --rm functional-tests
docker compose config --quiet

Backup

Back up the database and WordPress files at the same logical point in time:

docker compose stop wordpress
mkdir -p backups
docker compose exec -T db sh -c 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE"' > backups/database.sql
tar -C runtime -czf backups/wordpress-files.tgz wordpress
docker compose start wordpress

Do not commit backups or .env. Encrypt and test real backups off-host. See operations before restoring or deleting volumes.

Rollback

Revert the application commit and rebuild containers. Preserve the host directories configured by DB_DATA_PATH, WORDPRESS_DATA_PATH, LETSENCRYPT_DATA_PATH, and CERTBOT_CHALLENGES_PATH. Database restoration is a separate, destructive operation and requires a verified backup.

S
Description
No description provided
Readme 422 KiB
Languages
Markdown 100%