fix(deploy): provision tenant API domains
Some checks failed
Architecture Governance / architecture (push) Failing after 6m16s
Some checks failed
Architecture Governance / architecture (push) Failing after 6m16s
Reconcile TLS, exact CORS, and backend proxying before release activation so every storefront uses its derived API host.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
# Deployment — server provisioning, CD, TLS
|
||||
|
||||
Frontend only. The backend service (`:8080`) is a separate developer's responsibility. API hostnames are separate reverse proxies and will return `502` until their upstream exists.
|
||||
Frontend deployment plus API-domain edge configuration. The backend service is a
|
||||
separate developer's responsibility. API hostnames are separate reverse proxies
|
||||
and return `502` until their configured upstream exists (production currently
|
||||
defaults to `https://127.0.0.1:445`).
|
||||
|
||||
**Multi-tenant, one bundle.** Every customer domain is served by the same build. The SPA resolves its tenant from the `Host` header ([BACKEND-HANDOFF §1a](backend/BACKEND-HANDOFF.md)). One deploy updates every domain simultaneously — there is no per-tenant build and no per-tenant deploy.
|
||||
|
||||
@@ -18,6 +21,7 @@ nested names such as `api.store1.example.com`.
|
||||
|---|---|
|
||||
| `scripts/deploy/server-setup.sh` | One-time server provisioning. Idempotent. Run as root. |
|
||||
| `scripts/deploy/add-domain.sh` | Attach one domain + issue TLS. Run per domain, as root, after DNS resolves. |
|
||||
| `scripts/deploy/configure-api-domain.sh` | Configure `api.<full storefront host>` TLS, exact CORS, backend proxy, and JSON bootstrap verification. |
|
||||
| `.github/workflows/deploy.yml` | CD: build → upload → atomic swap → verify. Triggers on push to `main`. |
|
||||
|
||||
---
|
||||
@@ -56,7 +60,10 @@ Copy `scripts/deploy/` to the server and run:
|
||||
sudo bash server-setup.sh --pubkey "$(cat marketplaces_deploy.pub)"
|
||||
```
|
||||
|
||||
This installs nginx + certbot, creates a **key-only** `deploy` user with no password, writes the catch-all nginx config, opens 80/443/OpenSSH in ufw, and grants `deploy` exactly one sudo right: `systemctl reload nginx`.
|
||||
This installs nginx + certbot, creates a **key-only** `deploy` user with no
|
||||
password, writes the catch-all nginx config, opens 80/443/OpenSSH in ufw, and
|
||||
installs a root-owned, argument-validating API-domain helper. The deploy user may
|
||||
run that helper and reload nginx, but cannot replace the helper.
|
||||
|
||||
Verify before continuing:
|
||||
|
||||
@@ -82,6 +89,15 @@ The output is the `DEPLOY_KNOWN_HOSTS` secret. Pinning it means a rebuilt or imp
|
||||
| `DEPLOY_USER` | `deploy` |
|
||||
| `DEPLOY_SSH_KEY` | contents of the **private** key file |
|
||||
| `DEPLOY_KNOWN_HOSTS` | output of `ssh-keyscan -H <server-ip>` |
|
||||
| `STOREFRONT_DOMAINS` | space-separated full hosts, e.g. `gorbushka.market store1.example.com` |
|
||||
| `CERTBOT_EMAIL` | operations email used for Let's Encrypt |
|
||||
| `BACKEND_UPSTREAM` | optional; defaults to `https://127.0.0.1:445` |
|
||||
|
||||
Before deploying, point every derived API hostname at the server. For the
|
||||
example above, DNS must resolve both `api.gorbushka.market` and
|
||||
`api.store1.example.com`. The workflow deliberately stops before release
|
||||
activation if DNS, certificate issuance, nginx validation, or the JSON
|
||||
`/bootstrap` check fails.
|
||||
|
||||
### 3.5 Deploy
|
||||
|
||||
|
||||
Reference in New Issue
Block a user