Initial commit: Imperva WAF demo lab
Flight-booking app scaffolded from the source running on the GCP host, plus the four-screen frontend and three OWASP attack endpoints (SQLi, reflected XSS, path traversal) built and locally verified against a live uvicorn/vite dev pair. Includes deploy.sh (local build -> ship over ssh -> swap on host) and docs/ carried over from the handoff.
This commit is contained in:
commit
4d60fdd139
28 files changed
+2609
No files matched your search
@@ -0,0 +1,95 @@
|
||||
# Deploy Workflow
|
||||
|
||||
Local code → finished image shipped over SSH → container swapped on the host. No
|
||||
container registry (see DECISIONS.md D8 for why).
|
||||
|
||||
## The two channels to the host
|
||||
|
||||
Both go to the same GCP box; they're used for different steps:
|
||||
|
||||
- **`podman save … | ssh … podman load`** — ships the image *bytes*. This has to use
|
||||
raw `ssh` because it's a pipe into the remote Podman CLI.
|
||||
- **`podman --connection gcp-lab …`** — swaps the running container over the existing
|
||||
rootless socket, hands-free (no manual SSH). The alias is already configured and set
|
||||
as default:
|
||||
`ssh://matt@35.203.147.44:22/run/user/1001/podman/podman.sock`.
|
||||
|
||||
> The socket is under **UID 1001** on this host (the original architecture doc's 1000 is
|
||||
> wrong). Using the alias means you never have to think about the UID.
|
||||
|
||||
## Why build locally
|
||||
|
||||
The `e2-micro` can't build the Vue multi-stage image reliably (memory). Always build on
|
||||
the local workstation and ship the finished image. Never build on the host.
|
||||
|
||||
## `deploy.sh`
|
||||
|
||||
Lives at the repo root and is run from there (so the relative `./backend` and
|
||||
`./frontend` build contexts resolve). Config block at the top holds host/user/key/alias.
|
||||
|
||||
Usage:
|
||||
|
||||
```bash
|
||||
./deploy.sh # full cycle: build both, ship both, swap both containers
|
||||
VERSION=v2 ./deploy.sh # tag images v2 instead of a timestamp → named rollback point
|
||||
./deploy.sh --build --ship --swap # explicit equivalent of the default
|
||||
./deploy.sh --restart-caddy # after editing the Caddyfile to add/modify routes
|
||||
```
|
||||
|
||||
With no arguments it runs `build → ship → swap`. `VERSION` defaults to a timestamp; set
|
||||
it explicitly to create a named point you can redeploy later.
|
||||
|
||||
## Steps the script performs
|
||||
|
||||
1. **build** — `podman build` the backend and frontend images locally.
|
||||
2. **ship** — `podman save <img> | ssh -i <key> matt@35.203.147.44 'podman load'` for
|
||||
each image.
|
||||
3. **swap** — over `--connection gcp-lab`: `rm -f` then `run -d` each container with its
|
||||
name and port mapping.
|
||||
4. **restart-caddy** (on demand) — `podman --connection gcp-lab restart caddy-proxy`,
|
||||
needed only when the Caddyfile changed (e.g. new XSS/traversal routes).
|
||||
|
||||
## IMPORTANT: keep `swap()` in sync with real run flags
|
||||
|
||||
The current `swap()` recreates containers with only `--name` and `-p`. It does **not**
|
||||
yet reproduce any bind mounts (e.g. the SQLite `demo.db`), config-file mounts, or
|
||||
network/DNS-alias flags the real containers depend on. **Before relying on the script,
|
||||
confirm the actual `podman run` flags** the current `backend-api` and `frontend-vue`
|
||||
were created with and fold them into `swap()`, or a deploy will silently drop them.
|
||||
|
||||
To inspect what the running containers actually use:
|
||||
|
||||
```bash
|
||||
podman --connection gcp-lab inspect backend-api | jq '.[0].Mounts, .[0].NetworkSettings'
|
||||
podman --connection gcp-lab inspect frontend-vue | jq '.[0].Mounts, .[0].NetworkSettings'
|
||||
```
|
||||
|
||||
## Caddy config / cert deploys
|
||||
|
||||
The Caddyfile and certs live on the host at `~/imperva-proxy/` and are bind-mounted
|
||||
read-only into `caddy-proxy`. To change routing:
|
||||
|
||||
1. Edit `imperva-proxy/Caddyfile` in the repo, copy it to the host `~/imperva-proxy/`.
|
||||
2. Validate before restarting so you're not debugging from a crash loop:
|
||||
```bash
|
||||
podman --connection gcp-lab exec caddy-proxy caddy validate --config /etc/caddy/Caddyfile
|
||||
```
|
||||
3. `./deploy.sh --restart-caddy`.
|
||||
|
||||
If the container is already crash-looping and `exec` won't attach, validate against the
|
||||
mount with a throwaway container instead:
|
||||
|
||||
```bash
|
||||
podman run --rm -v /home/matt/imperva-proxy/Caddyfile:/etc/caddy/Caddyfile:ro,Z \
|
||||
docker.io/library/caddy:2-alpine caddy validate --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
## Verifying a deploy
|
||||
|
||||
- Origin health from the host (self-signed, so `-k`):
|
||||
```bash
|
||||
podman --connection gcp-lab exec caddy-proxy sh -c 'wget -qO- --no-check-certificate https://localhost/ | head'
|
||||
```
|
||||
(or `curl -vk https://localhost/` directly on the host)
|
||||
- Real path end to end: load `https://flytoouter.space/` in a browser — should show
|
||||
Imperva's trusted edge cert while the origin serves self-signed to Imperva only.
|
||||
Reference in new issue
Block a user