Any change that alters user-facing flow must also be reflected in guide.md. This ensures the beginner deployment guide stays accurate as the codebase evolves. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
101 lines
5.6 KiB
Markdown
101 lines
5.6 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Critical Rules
|
|
|
|
- **NEVER build, test, or run anything locally.** Always use Docker for all build/test/run operations.
|
|
- **`websitebox-brief (2).md` is the source of truth** for all project decisions and specifications. Always defer to it.
|
|
- **Do not load `websitebox-diagram (1).jsx`** unless the user explicitly asks for it — it is reference material only.
|
|
- **Keep `guide.md` in sync.** Any change that alters the user-facing flow — new commands, renamed scripts, changed setup wizard prompts, added/removed steps, new dependencies, modified ports, updated troubleshooting — **must** also be reflected in `guide.md`. This is a beginner-facing deployment guide in ProjectPublic markup format. If you're unsure whether a change affects the guide, check. Treat guide.md as a living document that must always match the actual codebase.
|
|
|
|
## Project Overview
|
|
|
|
WebsiteBox is a Docker-based, self-hosted WordPress deployment system. Users provision a VPS, run an install script, and get a working SSL-secured WordPress portfolio site with `docker compose up -d`. The project prioritizes zero-trust transparency, minimal CLI interaction, and VPS-agnostic deployment.
|
|
|
|
## Architecture
|
|
|
|
Four-container Docker Compose stack on a single Docker network (`websitebox_internal`):
|
|
|
|
- **nginx** (custom `nginx:alpine`) — Reverse proxy, SSL termination via Let's Encrypt. Only container exposing ports (80, 443). Entrypoint auto-acquires SSL certs on first boot.
|
|
- **wordpress** (custom `wordpress:php8.2-fpm-alpine`) — PHP-FPM with WP-CLI bundled. First-boot entrypoint installs WordPress core, GeneratePress theme, child theme, and plugins (Age Gate, Wordfence, UpdraftPlus) via WP-CLI.
|
|
- **db** (`mariadb:11`) — Internal only, never exposed to host.
|
|
- **certbot** (`certbot/certbot`) — Renewal loop every 12h, signals nginx via shared volume file trigger (no Docker socket mount).
|
|
|
|
All persistent data uses **bind mounts** under `./websitebox-data/` (not named Docker volumes):
|
|
- `wordpress/`, `database/`, `certs/`, `certbot-webroot/`, `certbot-signal/`, `backups/`
|
|
|
|
## Key Design Decisions
|
|
|
|
- **Restart policy**: `restart: unless-stopped` on all containers (not `always`).
|
|
- **SSL bootstrap**: Handled entirely in nginx entrypoint — no separate ssl-init.sh script. Nginx detects missing certs, serves HTTP for ACME challenge, acquires certs, reloads with SSL.
|
|
- **Certbot-to-nginx reload**: Certbot writes trigger file to shared `certbot-signal/` volume; nginx background loop detects and reloads. No Docker socket mounting.
|
|
- **WordPress setup**: All via WP-CLI in container entrypoint, not the mu-plugin. Uses marker files (`.websitebox-setup-complete` / `.websitebox-setup-partial`) for idempotency.
|
|
- **Backup path**: UpdraftPlus writes to `/var/backups/websitebox` (mapped to `./websitebox-data/backups/`), deliberately outside `/var/www/html` to avoid nested bind mount conflicts.
|
|
- **XML-RPC disable**: In mu-plugin via `add_filter('xmlrpc_enabled', '__return_false')`, NOT in wp-config.php (plugin API not loaded at wp-config time).
|
|
- **WP-CLI**: Bundled in WordPress Docker image. Run commands as `www-data`, never use `--allow-root`.
|
|
- **Table prefix**: `wbox_` (not default `wp_`).
|
|
- **wp-config**: Sets `DISALLOW_FILE_EDIT` (blocks theme/plugin editor) but NOT `DISALLOW_FILE_MODS` (would prevent plugin/theme updates via admin GUI).
|
|
|
|
## User Flow
|
|
|
|
1. `curl -fsSL <url>/install.sh | bash` — installs Docker, clones repo, runs setup wizard
|
|
2. `setup.sh` — interactive wizard, generates `.env`, creates `websitebox-data/` structure
|
|
3. User configures DNS A record
|
|
4. `docker compose up -d` — everything self-configures
|
|
|
|
## File Structure Conventions
|
|
|
|
- `nginx/entrypoint.sh` — SSL auto-bootstrap logic
|
|
- `wordpress/entrypoint.sh` — First-boot WP-CLI setup (theme/plugin install, site config)
|
|
- `wordpress/wp-content/mu-plugins/websitebox-setup.php` — Lightweight status checker + XML-RPC disable (not the installer)
|
|
- `wordpress/wp-content/themes/websitebox/` — Child theme (parent: GeneratePress)
|
|
- `scripts/` — `backup.sh`, `update.sh`, `ssl-renew.sh`, `healthcheck.sh`
|
|
- `.env` / `.env.example` — Configuration (gitignored / template)
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Start the stack
|
|
docker compose up -d
|
|
|
|
# Rebuild after Dockerfile changes
|
|
docker compose up -d --build
|
|
|
|
# View logs
|
|
docker compose logs -f [service]
|
|
|
|
# Restart a specific service
|
|
docker compose restart wordpress
|
|
|
|
# Re-run first-boot setup (force clean)
|
|
docker compose exec wordpress rm /var/www/html/.websitebox-setup-complete /var/www/html/.websitebox-setup-partial
|
|
docker compose restart wordpress
|
|
|
|
# Update WebsiteBox
|
|
./scripts/update.sh
|
|
|
|
# Manual backup
|
|
./scripts/backup.sh
|
|
```
|
|
|
|
## Healthchecks
|
|
|
|
| Service | Check | Retries |
|
|
|---------|-------|---------|
|
|
| nginx | `curl -f http://localhost/nginx-health` | 3 |
|
|
| wordpress | `php-fpm-healthcheck` | 3 |
|
|
| db | `healthcheck --su-mysql --connect --innodb_initialized` | 5 |
|
|
|
|
WordPress depends on db with `condition: service_healthy`.
|
|
|
|
## Error Handling Patterns
|
|
|
|
- WordPress entrypoint: MariaDB retry loop (30 attempts, 2s apart). On partial failure, creates `.websitebox-setup-partial` marker and starts PHP-FPM anyway. All WP-CLI commands are idempotent — safe to re-run entire sequence.
|
|
- nginx entrypoint: On SSL failure, serves HTTP placeholder explaining DNS isn't ready. User retries with `docker compose restart nginx`.
|
|
- install.sh: Uses `sg docker` for immediate Docker group activation without logout/login.
|
|
|
|
## Non-Goals (v1)
|
|
|
|
Payment processing, multi-site WordPress, automatic VPS provisioning, built-in CDN, email server (SMTP relay config only).
|