Deployed Dev Environment
The deployed dev environment is Wavemap’s shared cloud-backed validation target. It is production-like where that gives
release confidence, but it remains cost-first, disposable by default, and intentionally smaller than a future staging or
production environment.
Local development and deployed dev are different trust boundaries. Local .env.dev files, local Docker, emulator
credentials, and personal profiles are developer-machine inputs. Deployed dev values come from GitHub environment
configuration, Pulumi stack config and outputs, AWS runtime stores, and deploy-time renderers.
Selected Shape
Section titled “Selected Shape”| Surface | Current Decision |
|---|---|
| Cloud provider | AWS is the first implemented provider. |
| Pulumi stack | aws-dev; routine CD reads deployment contracts, while infra operators use the Pulumi backend. |
| Runtime region | us-east-2 for regional runtime resources. |
| Public app URL | https://dev.wavemap.app. |
| Runtime target | Sleepable EC2 host running Docker Compose. |
| Runtime containers | Frontend, backend API, and Postgres. |
| Database | Containerized Postgres on the runtime host, disposable and reseedable for dev. |
| Media storage | Private S3 bucket, with browser-facing media served through same-origin CloudFront /media/*. |
| Registry | Private ECR repositories for backend and frontend deploy images. |
| Operator access | SSM Session Manager. No routine SSH ingress. |
| Docs site | Independent static surface at https://docs.wavemap.app; not served by this runtime. |
The runtime host starts from Amazon Linux 2023, installs Docker during bootstrap, and keeps application release state
under /opt/wavemap. Pulumi owns the host, security group, IAM role, deployment command document, and output contract.
The deploy workflow owns image selection, env rendering, Compose updates, container restart, smoke checks, and runtime
release receipts.
For command contracts, wrapper paths, key flags, and default mutation posture, use the Deploy Dev and Smoke sections of the CLI command reference.
Cost Posture
Section titled “Cost Posture”Deployed dev should choose the lowest-cost shape that still preserves useful deployment confidence and acceptable demo
UX. The current t3a.medium runtime host is an explicit exception to the smallest-host instinct because the frontend,
backend, Postgres, Docker, and smoke checks share one VM.
The environment uses a sleepable-host model:
- CloudFront remains the stable public app front door.
- The EC2 runtime host can stop when idle.
- A wake path starts the host and refreshes the dynamic origin when someone returns.
- A shutdown Lambda owns deliberate host stop.
- An inactivity monitor can invoke that same shutdown path after request inactivity.
Host stop is cost control. It is not data cleanup, database reset, media cleanup, backup, or stack teardown.
Value Ownership
Section titled “Value Ownership”| Source | Owns | Notes |
|---|---|---|
GitHub dev environment variables | Non-secret workflow bootstrap values. | Examples include selected provider, deployment environment, or Pulumi stack selectors. |
GitHub dev environment secrets | Deploy-time credentials or role ARNs. | App runtime secrets should not be mirrored here unless explicitly documented as a temporary bridge. |
| Pulumi stack config | Infrastructure choices and Pulumi-owned secrets. | Use Pulumi secrets only for values that belong to infrastructure state. |
| Deployment contract | Sanitized non-secret deployment facts. | Routine deploy commands consume registry URLs, runtime host paths, ingress facts, and explicit SSM executor handles here. |
| Pulumi outputs | Infra-operator source facts. | Approved outputs are projected into the deployment contract rather than read directly by routine CD. |
| AWS SSM Parameter Store | App runtime config and runtime secrets. | Preferred runtime store for /wavemap/dev/runtime/* values. |
| EC2 rendered env files | Container process environment. | Generated during deploy; never committed. |
| Docker build args | Browser-visible frontend build values. | NEXT_PUBLIC_* values are public and must not be treated as secrets. |
Before adding, renaming, or removing environment variables, runtime config, build inputs, secrets, deployment contract fields, Pulumi outputs, or runtime parameters, follow Configuration And Secrets.
Runtime Config Documentation Boundary
Section titled “Runtime Config Documentation Boundary”Runtime config does not currently need a dedicated operations page. The stable material is intentionally split by ownership:
| Home | Owns |
|---|---|
| Configuration And Secrets | Cross-cutting source classification, visibility, secret handling, and verification rules. |
| This page | Current deployed-dev value ownership, runtime store, and environment shape. |
| Runtime Config Readiness | Repeated operator procedure for planning, populating, and checking runtime config readiness. |
| Deployment Workflows | CD ordering, cloud-plan checks, deploy-time secret boundary, and runtime host handoff. |
Create a dedicated operations page only when the operator surface outgrows the runbook, such as multi-environment runtime config promotion, routine rotation procedures, or a larger SSM inventory lifecycle.
Runtime And Data Lifecycle
Section titled “Runtime And Data Lifecycle”The deployed-dev data posture is intentionally modest. Different operations have different data consequences:
- Container restart and Compose restart should preserve the Postgres host path when that path is untouched.
- EC2 stop/start should preserve the root EBS volume and therefore the current Postgres host path.
- Destructive database reset is explicit and should not be hidden behind standby or host shutdown.
- Media objects persist across host stop/start.
- Media objects can become application-orphaned after destructive database reset.
- The media bucket is disposable at the infrastructure lifecycle level; replacement or stack teardown can delete objects.
- Backup/restore is a learning drill for this environment, not a production disaster-recovery guarantee.
Use Deployed Dev Lifecycle for the detailed lifecycle matrix, standby/teardown gradations, and expected evidence. Use Data Durability And Recovery for reset, media drift, backup learning-drill, and later-environment recovery gates. The reviewed operator procedures live in Runbooks.
Control Plane
Section titled “Control Plane”The deployed-dev control plane is intentionally small:
- CloudFront terminates public TLS for
dev.wavemap.app. - Ordinary app traffic routes to the dynamic origin
app-origin.dev.wavemap.app. - The static cold-start origin serves a Wavemap loading page while the runtime host is stopped or warming up.
- The
/__wakeroute starts the runtime host through a Lambda Function URL guarded by a CloudFront origin header. - The shutdown Lambda is invoked through AWS IAM only; it has no public route.
- The inactivity monitor reads CloudFront request activity and invokes the shutdown Lambda after the configured quiet window.
The wake, shutdown, and inactivity Lambdas do not own app release state, database reset, backup, media cleanup, or stack teardown.
Approval Boundaries
Section titled “Approval Boundaries”These actions remain explicit human decisions:
- Pulumi preview/update for shared environment infrastructure.
- IAM, OIDC trust, DNS, certificate, or deploy-role changes.
- Runtime database reset.
- Cold-start browser smoke that deliberately stops the shared runtime host.
- Stack teardown or replacement of persistent/data-bearing resources.
Routine app/API CD can deploy new SHA-tagged images and run endpoint smoke. It should not silently widen into infrastructure mutation or data lifecycle work.