# Docker production edge runbook

Status: rehearsal-ready; not authorized for public deployment until Blueprint Stage 9.

## Security boundary

`docker-compose.production.yml` publishes only nginx ports 80 and 443. The
registration service, game bridge, and asset stream share the edge container's
network namespace and bind only to `127.0.0.1`. They therefore have no separate
container address or published port. The edge joins an operator-selected backend
network so the sidecars can reach Cosmic and MySQL without exposing either one.

The HTTP listener serves only `/healthz` and otherwise redirects to HTTPS.
Registration and gameplay remain disabled by the browser when the origin is not
a secure context.

## Required operator inputs

- a DNS hostname whose A/AAAA record reaches the public edge;
- a trusted certificate and unencrypted PEM private key for that hostname;
- a router/firewall forward for TCP 80 and 443 to the Docker host;
- the exact packaged release directory;
- the lawful, manifest-validated v83 asset directory;
- an existing private Docker network that reaches pinned Cosmic and MySQL;
- an INSERT-only Cosmic registration identity and a host-restricted file
  containing only its password.

Copy `.env.production.example` to an ignored, host-restricted environment file
and replace every example value. Do not place a password directly in that file.

## Preflight and rehearsal

Package a clean release, then run:

```powershell
python web/e2e/docker_edge_rehearsal.py
docker compose --env-file .env.production -f docker-compose.production.yml config --quiet
```

The rehearsal uses random loopback ports, a one-use self-signed certificate, an
ephemeral Docker network, the restricted game bridge, a disposable TCP echo
target, and digest-pinned disposable MySQL initialized from the pinned Cosmic
account schema. It proves HTTP redirect, HTTPS static delivery, isolation
headers, non-cacheable entry/config files, immutable built files, WASM MIME and
byte ranges, dotfile denial, WSS upgrade/echo, CSRF-protected registration,
column-limited INSERT grants, cost-12 bcrypt storage, exact edge-only port
publication, and cleanup without modifying unrelated running containers. It
does not establish public certificate trust, NAT reachability, lawful assets,
Cosmic gameplay login, asset streaming, or persistent-database readiness.

## Stage 9 commands

Only after every prior blueprint gate passes:

```powershell
docker compose --env-file .env.production -f docker-compose.production.yml build --pull
docker compose --env-file .env.production -f docker-compose.production.yml up -d --wait
docker compose --env-file .env.production -f docker-compose.production.yml ps
```

Record the resolved image digests and release manifest before rollout. External
probes must confirm that only 80/443 were added, 80 redirects, TLS is trusted,
WSS remains connected beyond 60 seconds, and no Cosmic/MySQL/sidecar port is
reachable.

Rollback uses the previously recorded release directory and image digests, then
recreates only the `mapleweb-production` Compose project. Never stop or recreate
unrelated Docker projects. Database backup/restore and rollback rehearsal remain
mandatory Stage 8/9 evidence before these commands are authorized publicly.
