Files
ShiErFeng/docs/superpowers/plans/2026-09-27-mysql-compose-bootstrap.md
T

78 lines
5.6 KiB
Markdown

# MySQL Initialization and Docker Compose Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Keep the MySQL fresh-install script aligned with the current business model and provide a safe, persistent Compose deployment for the frontend, backend, MySQL, and Redis.
**Architecture:** The existing MySQL initializer remains the single bootstrap source for a new empty database and is mounted into MySQL's first-start initialization directory. Existing database volumes are never migrated automatically; operators continue to use the reviewed MySQL patches separately. Compose keeps MySQL and Redis on an internal network, persists their data in named volumes, and reads credentials from an ignored local `.env` file created from a checked-in example.
**Tech Stack:** MySQL 8.0, Redis 7, existing FastAPI and Vue/Nginx Dockerfiles, Docker Compose v2, Python `unittest` schema contracts.
**Spec:** User request; schema/seed contract in `shierfeng-fastapi-backend/tests/module_business/test_sql_contract.py`; operational migration guidance in `docs/test-data-batch-operations.md` and `docs/pallet-workflow-deployment.md`.
## Global Constraints
- MySQL remains the only database engine; do not add PostgreSQL configuration or SQL files.
- Do not execute SQL, apply patches, start containers, or remove/replace any database volume as part of this change.
- The full initializer contains `DROP TABLE`; mount it only as a first-start script for a fresh MySQL data directory.
- Keep existing seed records and schema unchanged when the current contract tests confirm they are synchronized.
- Do not place real credentials in Compose or the checked-in example environment file.
- Preserve unrelated staged, unstaged, and untracked work already in the repository.
---
### Task 1: Mark the MySQL initializer's safe-use boundary
**Files:**
- Modify: `shierfeng-fastapi-backend/sql/shierfeng-fastapi.sql`
- Test: `shierfeng-fastapi-backend/tests/module_business/test_sql_contract.py`
**Interfaces:**
- Consumes: current SQLAlchemy ORM table metadata and the existing MySQL SQL contract tests.
- Produces: the same schema and seed statements, with a clear warning that this destructive bootstrap is only for an empty/new database.
- [x] Add a Chinese header warning that the script drops/recreates tables and is for a fresh empty database only; direct existing-database users to reviewed files under `sql/patches/`.
- [x] Run the existing SQL contract suite and confirm all table, field, constraint, menu, and test-batch contracts still pass.
- [x] Review the diff to confirm no seed rows or DDL changed beyond the warning.
### Task 2: Add a persistent full-stack Docker Compose deployment
**Files:**
- Create: `docker-compose.yml`
- Create: `.env.docker.example`
- Modify: `.gitignore`
**Interfaces:**
- Consumes: `Dockerfile.my`, the frontend `Dockerfile`, `nginx.dockermy.conf`, `.env.dockermy`, and the MySQL initializer.
- Produces: Compose services `shierfeng-mysql`, `shierfeng-redis`, `shierfeng-backend-my`, and `shierfeng-frontend`; named volumes `mysql-data` and `redis-data`; required secrets supplied by root `.env`.
- [x] Define MySQL 8.0 with the fresh-install SQL mounted read-only at `/docker-entrypoint-initdb.d/01-schema-and-seed.sql`, an app-scoped database user, a health check, and a named data volume.
- [x] Define Redis 7 with append-only persistence, a health check, and a named data volume; do not publish Redis to the host.
- [x] Build the backend and frontend from the existing Dockerfiles. Configure backend DB/Redis service hosts and credentials through Compose environment overrides; make backend wait for healthy dependencies.
- [x] Route browser API requests through the existing Nginx config. Publish the frontend on configurable host port 8080 by default and MySQL only on loopback port 13307 by default.
- [x] Create `.env.docker.example` with placeholders for MySQL root password, app DB username/password, and JWT secret; add only root `/.env` to `.gitignore`.
- [x] Run `docker compose config --quiet` with test-only environment values and confirm configuration resolves without starting services.
### Task 3: Document first-run and existing-database workflows
**Files:**
- Modify: `README.md`
**Interfaces:**
- Consumes: root Compose file and `.env.docker.example`.
- Produces: concise setup commands and explicit distinction between fresh database initialization and existing-database patches.
- [x] Replace the root deployment instructions that point to the test-only Compose file with instructions to copy `.env.docker.example` to `.env`, set strong local credentials, validate with `docker compose config`, and start with `docker compose up -d --build`.
- [x] Document the default frontend/MySQL addresses and state that MySQL initialization scripts run only when its data directory is empty; existing databases must use reviewed patches after backup.
- [x] Do not include `docker compose down -v` or any other volume-deletion command in the documentation.
- [x] Re-run the SQL contract suite and Compose config validation; do not run `docker compose up`.
## Verification Commands
```bash
PYTHONDONTWRITEBYTECODE=1 /Users/jiaolongyan/miniconda3/envs/ShiErFeng/bin/python -m unittest tests.module_business.test_sql_contract -v
MYSQL_ROOT_PASSWORD=compose-validation DB_USERNAME=compose_validation DB_PASSWORD=compose-validation JWT_SECRET_KEY=compose-validation docker compose config --quiet
```
Do not run the SQL initializer, migration patches, or `docker compose up` during implementation verification.