Add dedicated setup.test.sh / restart.test.sh for the staging stack

Both refuse to run unless docker/.env names a non-prod COMPOSE_PROJECT_NAME and
scope every compose call to that project.

setup.test.sh: like setup.sh but runs the DB/cache/console steps as www-data and
repairs var/cache|log|sessions ownership at the end, so php-fpm can read its own
compiled cache (bare `docker exec` runs as root -> silent 500s). Never touches
var/volumes/db. Test-appropriate final message (NPM upstream, local curl check).

restart.test.sh: keeps the database by default (--fresh-db to wipe + re-init),
never runs a host-wide docker prune, and only chowns var/cache|log|sessions
(chowning var/volumes/db is what corrupted the MySQL data dir).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Frank
2026-08-31 00:19:13 +02:00
co-authored by Claude Sonnet 5
parent b565825cd9
commit 97d35f8fcb
4 changed files with 251 additions and 18 deletions
+30 -17
View File
@@ -71,11 +71,17 @@ already supplied to the containers by `docker/.env`.
### 5. Build & start
```bash
./docker/setup.sh
./docker/setup.test.sh
```
The test-specific script (not `setup.sh`): it refuses to run unless
`COMPOSE_PROJECT_NAME` in `docker/.env` is a non-prod value, scopes every compose
call to that project, runs the DB/cache/console steps as `www-data`, and repairs
`var/cache` / `var/log` / `var/sessions` ownership at the end (bare `docker exec`
runs as root, which otherwise leaves php-fpm unable to read its own cache — a
silent 500). It never touches `var/volumes/db`.
Builds `escapepage-test-*` images, starts the containers, creates + migrates
`escapepage_test`, builds assets. Re-run any time; `--no-build` skips the image
rebuild.
`escapepage_test`, builds assets. Re-run any time; `--no-build` skips the rebuild.
### 6. Nginx Proxy Manager — proxy host
- Domain: `test.escapepage.com`
@@ -114,25 +120,32 @@ deny all;
## Deploying a new version to test
```bash
cd /opt/escapepage-test
cd /var/sites/escapepage-test
git fetch && git checkout <branch> && git pull
docker compose -f docker/compose.yaml -f docker/compose.override.yaml \
exec php composer install
docker compose ... exec php php bin/console doctrine:migrations:migrate -n
docker compose ... exec php php bin/console cache:clear
docker compose ... exec php npm ci && ... npm run build
docker restart escapepage-test-php-worker
./docker/setup.test.sh --no-build # composer install, migrate, build assets, fix perms
```
`--no-build` skips the image rebuild; drop it if the Dockerfile changed.
## Restarting
```bash
./docker/restart.test.sh # down + up, keeps the DB and images
./docker/restart.test.sh --build # also rebuild images
./docker/restart.test.sh --fresh-db # also wipe var/volumes/db and re-init MySQL
```
(Or just `./docker/setup.sh --no-build`.)
## Safety notes
- **`docker/restart.sh` is now scoped to `STACK_NAME` / `COMPOSE_PROJECT_NAME`**
from `docker/.env` — running it in the test checkout only touches
`escapepage-test-*`. The host-wide
`docker system prune` / `docker builder prune` it used to always run are now
opt-in via `./docker/restart.sh --prune-all`; don't use that flag while the
other stack shares the host.
- Use the **`*.test.sh`** scripts on this checkout, not `setup.sh` / `restart.sh`.
Both refuse to run unless `docker/.env` names a non-prod
`COMPOSE_PROJECT_NAME`, and both scope every action to that project — they
can't reach the production stack.
- `restart.test.sh` **keeps the database** by default (you loaded prod data into
it); `--fresh-db` is the only thing that wipes it. It never runs a host-wide
`docker system prune` / `docker builder prune`, and it only repairs ownership
of `var/cache` / `var/log` / `var/sessions` — **never `var/volumes/db`**
(chowning the MySQL data dir is what corrupted it earlier this build).
- The test `docker/.env` uses its own `DB_NAME` and passwords so a config slip
can't reach the production database.
- `MAILER_DSN=smtp://mailer:1026` keeps staging mail inside Mailpit instead of