deploy-stack 0.14.2 β†’ 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ You retain complete ownership of your infrastructure code without relying on bla
30
30
  **πŸš€ Zero-Config Deployments**
31
31
  * **Framework Agnostic:** Tailored container presets for Next.js, Express.js, FastAPI, Go, Django, Rails, Nuxt 3, and Static Sites (React, Vue, SvelteKit, Astro).
32
32
  * **Smart Discovery:** Automatically detects build output directories and generates highly optimized, multi-stage Dockerfiles.
33
- * **PaaS Migration Engine:** Natively parses Heroku `Procfile` configurations and `vercel.json` files to automatically translate proprietary edge routing (redirects/rewrites) and background workers into standard AWS Fargate and Application Load Balancer architectures.
33
+ * **Migration Engines:** Natively parses Heroku `Procfile` configurations, `vercel.json` routing rules, and `docker-compose.yml` sidecar architectures to automatically translate them into standard AWS Fargate and Application Load Balancer topologies.
34
34
  * **Database Scaffolding:** Automatically provisions fully isolated, zero-trust AWS RDS PostgreSQL databases for backend monoliths.
35
35
 
36
36
  **πŸ›‘οΈ DevSecOps & Security**
@@ -124,18 +124,11 @@ your-project/
124
124
  ## πŸ“¦ Reference Implementations
125
125
 
126
126
  * **[Next.js Fullstack App](https://github.com/anton-codes-iac/deploy-stack-nextjs-example):** A complete Next.js deployment showcasing the generated Terraform, CloudFront setup, and automated OIDC workflow.
127
- * **[Vercel to AWS Migration (Next.js)](https://github.com/anton-codes-iac/deploy-stack-vercel-nextjs-example):** Demonstrates automatic translation of Vercel edge routing (`vercel.json`) to native AWS Application Load Balancer rules.
128
- * **[Express.js API](https://github.com/anton-codes-iac/deploy-stack-express-example):** A standard Node.js backend setup.
129
- * **[Python FastAPI](https://github.com/anton-codes-iac/deploy-stack-fastapi-example):** A Python API demonstrating unprivileged port mapping.
130
- * **[Vite / React SPA](https://github.com/anton-codes-iac/deploy-stack-vite-example):** Demonstrates SPA routing and `dist/` auto-detection.
131
- * **[Create React App](https://github.com/anton-codes-iac/deploy-stack-cra-example):** Validates backward compatibility with legacy Webpack pipelines and `build/` auto-detection.
132
- * **[Astro Static Site](https://github.com/anton-codes-iac/deploy-stack-astro-example):** Demonstrates modern static site generation (SSG).
133
- * **[SvelteKit Application](https://github.com/anton-codes-iac/deploy-stack-svelte-example):** Demonstrates static adapter integration and custom output folder detection.
134
- * **[Ruby on Rails](https://github.com/anton-codes-iac/deploy-stack-rails-example):** A production Rails 7+ setup featuring an auto-provisioned PostgreSQL database and secure `.auto.tfvars` Master Key injection.
135
- * **[Nuxt 3 (SSR)](https://github.com/anton-codes-iac/deploy-stack-nuxt-example):** Demonstrates a fully server-side rendered Nuxt application using Nitro's optimized Node output.
136
- * **[Django / Python](https://github.com/anton-codes-iac/deploy-stack-django-example):** A secure Gunicorn/WSGI implementation with PostgreSQL and unprivileged container adapters.
137
- * **[Heroku to AWS Migration (Django)](https://github.com/anton-codes-iac/deploy-stack-heroku-django-example):** A classic Heroku-style monolith migrated via the Procfile Importer, demonstrating a multi-container Web and Celery Worker architecture deployed from a single codebase.
138
- * **[Go / Fiber](https://github.com/anton-codes-iac/deploy-stack-go-example):** A distroless, compiled Go binary deployment demonstrating ultra-low memory footprints and instant boot times.
127
+ * **[Docker Compose to AWS Migration](https://github.com/anton-codes-iac/deploy-stack-docker-compose-example):** Demonstrates automatic translation of local `docker-compose.yml` sidecars (like Redis) into a multi-container AWS ECS Task Definition communicating over `localhost`.
128
+ * **[Heroku to AWS Migration (Django)](https://github.com/anton-codes-iac/deploy-stack-heroku-django-example):** A classic Heroku-style monolith migrated via the Procfile Importer.
129
+
130
+ πŸ‘‰ **[View all 14+ reference implementations in our Examples Gallery](./docs/examples.md)**
131
+
139
132
  ---
140
133
 
141
134
  ## πŸ›‘οΈ Telemetry & Privacy
@@ -150,28 +143,14 @@ npx deploy-stack --no-telemetry
150
143
 
151
144
  ## πŸ—ΊοΈ Roadmap
152
145
 
153
- ### Phase 1–3: The Core Engine (Completed)
154
- - [x] **Core MVP:** Interactive CLI, ECS Fargate + ALB generation, CI/CD, and Secrets sync.
155
- - [x] **Production Readiness:** CloudFront CDN edge distribution, native S3 state locking, and secure OIDC integration.
156
- - [x] **Smart Experience:** Zero-config framework auto-discovery for static output directories.
157
- - [x] **Trust & Observability:** DevSecOps Trivy scanning, automated 5XX alarms, 14-day log retention, and safe local overwrite protections.
158
-
159
- ### Phase 4: Trust Anchors & TAM Expansion (Completed)
160
- - [x] **Ecosystem Distribution:** Native GitHub Marketplace Action for rapid discovery.
161
- - [x] **Cost Transparency:** Pre-flight AWS cost estimator injected directly into the CLI wizard.
162
- - [x] **Zero Vendor Lock-In:** Explicit `npx deploy-stack eject` command to safely strip `ManagedBy` tags and CLI metadata, leaving behind pure IaC.
163
- - [x] **Heavy Backend Monoliths:** Hardened, unprivileged container adapters for Go, Nuxt.js, Django, and Rails, complete with automated zero-trust RDS PostgreSQL provisioning.
164
-
165
- ### Phase 5: The Activation Engine (Completed)
166
- - [x] **Local Execution Wrapper:** Native `deploy-stack apply` command with terminal-optimized streaming to eliminate Terraform context switching.
167
- - [x] **Ecosystem Integrations:** Official plugins published to the Astro Integrations directory (`astro-deploy-stack`) and Nuxt module registry (`nuxt-deploy-stack`).
168
-
169
- ### Phase 6: Migration & Trust Engine (Current)
146
+ ### Current Focus (Phase 6: Migration & Trust Engine)
170
147
  - [x] **Dry-Run Visualization:** Interactive pre-flight terminal UI with ASCII topology maps and precise, dynamic AWS cost estimation.
171
148
  - [x] **PaaS Importers:** Auto-parse `vercel.json` and Heroku `Procfile` configurations to map routing rules, web commands, and background workers automatically.
172
- - [ ] **Docker Compose to ECS Translator:** Automatically converting a familiar local `docker-compose.yml` into production ECS task definitions.
149
+ - [x] **Docker Compose to ECS Translator:** Automatically converting a familiar local `docker-compose.yml` into production ECS task definitions.
173
150
  - [ ] **AI Agent Rulesets:** Publishing `.cursorrules` and Copilot instructions that teach AI assistants exactly how to utilize the CLI on the user's behalf.
174
151
 
152
+ πŸ‘‰ **[See the full project history and future plans in ROADMAP.md](./ROADMAP.md)**
153
+
175
154
  ---
176
155
 
177
156
  ## πŸ“œ License
@@ -0,0 +1,23 @@
1
+ # πŸ—ΊοΈ deploy-stack Roadmap
2
+
3
+ ### Phase 1–3: The Core Engine (Completed)
4
+ - [x] **Core MVP:** Interactive CLI, ECS Fargate + ALB generation, CI/CD, and Secrets sync.
5
+ - [x] **Production Readiness:** CloudFront CDN edge distribution, native S3 state locking, and secure OIDC integration.
6
+ - [x] **Smart Experience:** Zero-config framework auto-discovery for static output directories.
7
+ - [x] **Trust & Observability:** DevSecOps Trivy scanning, automated 5XX alarms, 14-day log retention, and safe local overwrite protections.
8
+
9
+ ### Phase 4: Trust Anchors & TAM Expansion (Completed)
10
+ - [x] **Ecosystem Distribution:** Native GitHub Marketplace Action for rapid discovery.
11
+ - [x] **Cost Transparency:** Pre-flight AWS cost estimator injected directly into the CLI wizard.
12
+ - [x] **Zero Vendor Lock-In:** Explicit `npx deploy-stack eject` command to safely strip `ManagedBy` tags and CLI metadata, leaving behind pure IaC.
13
+ - [x] **Heavy Backend Monoliths:** Hardened, unprivileged container adapters for Go, Nuxt.js, Django, and Rails, complete with automated zero-trust RDS PostgreSQL provisioning.
14
+
15
+ ### Phase 5: The Activation Engine (Completed)
16
+ - [x] **Local Execution Wrapper:** Native `deploy-stack apply` command with terminal-optimized streaming to eliminate Terraform context switching.
17
+ - [x] **Ecosystem Integrations:** Official plugins published to the Astro Integrations directory (`astro-deploy-stack`) and Nuxt module registry (`nuxt-deploy-stack`).
18
+
19
+ ### Phase 6: Migration & Trust Engine (Current)
20
+ - [x] **Dry-Run Visualization:** Interactive pre-flight terminal UI with ASCII topology maps and precise, dynamic AWS cost estimation.
21
+ - [x] **PaaS Importers:** Auto-parse `vercel.json` and Heroku `Procfile` configurations to map routing rules, web commands, and background workers automatically.
22
+ - [x] **Docker Compose to ECS Translator:** Automatically converting a familiar local `docker-compose.yml` into production ECS task definitions.
23
+ - [ ] **AI Agent Rulesets:** Publishing `.cursorrules` and Copilot instructions that teach AI assistants exactly how to utilize the CLI on the user's behalf.
@@ -0,0 +1,23 @@
1
+ # πŸ“¦ Reference Implementations & Examples
2
+
3
+ These repositories demonstrate how `deploy-stack` handles various frameworks and architectural patterns. Each example includes the auto-generated Terraform, GitHub Actions, and container configurations.
4
+
5
+ ### Featured Migrations
6
+ * **[Heroku to AWS Migration (Django)](https://github.com/anton-codes-iac/deploy-stack-heroku-django-example):** A classic Heroku-style monolith migrated via the Procfile Importer, demonstrating a multi-container Web and Celery Worker architecture deployed from a single codebase.
7
+ * **[Vercel to AWS Migration (Next.js)](https://github.com/anton-codes-iac/deploy-stack-vercel-nextjs-example):** Demonstrates automatic translation of Vercel edge routing (`vercel.json`) to native AWS Application Load Balancer rules.
8
+ * **[Docker Compose to AWS Migration](https://github.com/anton-codes-iac/deploy-stack-docker-compose-example):** Demonstrates automatic translation of local `docker-compose.yml` sidecars (like Redis) into a multi-container AWS ECS Task Definition communicating over `localhost`.
9
+
10
+ ### Frontend & Fullstack Frameworks
11
+ * **[Next.js Fullstack App](https://github.com/anton-codes-iac/deploy-stack-nextjs-example):** A complete Next.js deployment showcasing the generated Terraform, CloudFront setup, and automated OIDC workflow.
12
+ * **[Vite / React SPA](https://github.com/anton-codes-iac/deploy-stack-vite-example):** Demonstrates SPA routing and `dist/` auto-detection.
13
+ * **[Create React App](https://github.com/anton-codes-iac/deploy-stack-cra-example):** Validates backward compatibility with legacy Webpack pipelines and `build/` auto-detection.
14
+ * **[Astro Static Site](https://github.com/anton-codes-iac/deploy-stack-astro-example):** Demonstrates modern static site generation (SSG).
15
+ * **[SvelteKit Application](https://github.com/anton-codes-iac/deploy-stack-svelte-example):** Demonstrates static adapter integration and custom output folder detection.
16
+ * **[Nuxt 3 (SSR)](https://github.com/anton-codes-iac/deploy-stack-nuxt-example):** Demonstrates a fully server-side rendered Nuxt application using Nitro's optimized Node output.
17
+
18
+ ### Backend APIs & Monoliths
19
+ * **[Express.js API](https://github.com/anton-codes-iac/deploy-stack-express-example):** A standard Node.js backend setup.
20
+ * **[Python FastAPI](https://github.com/anton-codes-iac/deploy-stack-fastapi-example):** A Python API demonstrating unprivileged port mapping.
21
+ * **[Ruby on Rails](https://github.com/anton-codes-iac/deploy-stack-rails-example):** A production Rails 7+ setup featuring an auto-provisioned PostgreSQL database and secure `.auto.tfvars` Master Key injection.
22
+ * **[Django / Python](https://github.com/anton-codes-iac/deploy-stack-django-example):** A secure Gunicorn/WSGI implementation with PostgreSQL and unprivileged container adapters.
23
+ * **[Go / Fiber](https://github.com/anton-codes-iac/deploy-stack-go-example):** A distroless, compiled Go binary deployment demonstrating ultra-low memory footprints and instant boot times.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deploy-stack",
3
- "version": "0.14.2",
3
+ "version": "0.15.0",
4
4
  "description": "Provision production-ready AWS infrastructure and CI/CD pipelines in seconds.",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -46,6 +46,7 @@
46
46
  "@aws-sdk/client-sts": "3.1115.0",
47
47
  "@clack/prompts": "1.7.0",
48
48
  "dotenv": "17.4.2",
49
+ "js-yaml": "5.4.1",
49
50
  "picocolors": "1.1.1"
50
51
  }
51
52
  }
@@ -100,8 +100,10 @@ export async function destroyStack() {
100
100
  }
101
101
 
102
102
  // 3. Clean up the S3 State Bucket
103
+ let deleteS3Bucket = false;
104
+
103
105
  if (bucketName) {
104
- const deleteS3Bucket = await confirm({
106
+ deleteS3Bucket = await confirm({
105
107
  message: color.yellow(`AWS compute resources destroyed. Do you also want to permanently delete the S3 state bucket?\n (Select 'No' if you plan to run 'deploy-stack apply' later to spin this back up.)`),
106
108
  initialValue: false,
107
109
  });
@@ -20,6 +20,7 @@ import { handleExistingFiles } from '../utils/backup.js';
20
20
  import { estimateMonthlyCost } from '../utils/visualizer.js';
21
21
  import { getTargetDirectory, getProjectConfig } from '../utils/prompts.js';
22
22
  import { resolveDjangoWsgi, handleRailsCI } from '../utils/frameworks.js';
23
+ import { hasDockerCompose, parseDockerCompose } from '../utils/dockerCompose.js';
23
24
 
24
25
  const pkg = JSON.parse(fsSync.readFileSync(new URL('../../package.json', import.meta.url)));
25
26
  const CLI_VERSION = pkg.version;
@@ -42,11 +43,13 @@ export async function mainStack({ isHeadless = false, headlessOptions = {} } = {
42
43
  const detectedFramework = detectFramework(dirConfig.targetDir);
43
44
  const procfile = parseProcfile(dirConfig.targetDir);
44
45
  const vercelRules = parseVercelConfig(dirConfig.targetDir);
46
+ const dockerCompose = parseDockerCompose(dirConfig.targetDir);
45
47
 
46
48
  if (!isHeadless) {
47
49
  if (detectedFramework) log.success(`Auto-detected framework: ${detectedFramework.name}`);
48
50
  if (procfile && procfile.web) log.success(`Auto-detected Procfile (web command: ${procfile.web.join(' ')})`);
49
51
  if (vercelRules) log.success(`Auto-detected vercel.json (Migrating edge network rules)`);
52
+ if (dockerCompose) log.success(`Auto-detected docker-compose.yml (${dockerCompose.length} services mapped)`);
50
53
  }
51
54
 
52
55
  if (isHeadless) console.log(color.cyan(`πŸ€– Running deploy-stack in headless mode`));
@@ -56,6 +59,19 @@ export async function mainStack({ isHeadless = false, headlessOptions = {} } = {
56
59
  const djangoWsgi = await resolveDjangoWsgi(dirConfig.targetDir, procfile, config.framework, isHeadless);
57
60
  const disableDefaultCI = await handleRailsCI(dirConfig.targetDir, config.framework, isHeadless);
58
61
 
62
+ // 3.5 Docker Compose Overrides
63
+ if (dockerCompose && dockerCompose.length > 0) {
64
+ // Find the first service that has an exposed port
65
+ const webService = dockerCompose.find(s => s.port);
66
+ if (webService && webService.port) {
67
+ // Override the config port with the one from Docker Compose
68
+ config.port = webService.port.toString();
69
+ if (!isHeadless) {
70
+ console.log(color.cyan(` 🐳 Docker Compose overrides: Port set to ${config.port} via service "${webService.name}"`));
71
+ }
72
+ }
73
+ }
74
+
59
75
  // 4. Framework Migration Checks (Vercel Escape Hatch)
60
76
  if (config.framework === 'nextjs') {
61
77
  const nextConfig = analyzeNextConfig(dirConfig.targetDir);
@@ -126,7 +142,8 @@ export async function mainStack({ isHeadless = false, headlessOptions = {} } = {
126
142
  DJANGO_WSGI: djangoWsgi,
127
143
  DISABLE_DEFAULT_CI: disableDefaultCI,
128
144
  PROCFILE: procfile,
129
- VERCEL_RULES: vercelRules
145
+ VERCEL_RULES: vercelRules,
146
+ DOCKER_COMPOSE: dockerCompose
130
147
  });
131
148
 
132
149
  // 8. Telemetry
@@ -151,6 +168,7 @@ export async function mainStack({ isHeadless = false, headlessOptions = {} } = {
151
168
  has_worker: !!(procfile && procfile.worker),
152
169
  is_heroku_migration: !!procfile,
153
170
  is_vercel_migration: !!vercelRules,
171
+ is_docker_compose: !!dockerCompose,
154
172
  });
155
173
 
156
174
  s.stop('Infrastructure provisioned successfully!');
@@ -0,0 +1,64 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { load } from 'js-yaml';
4
+
5
+ // 1. Check if a Docker Compose file exists in the target directory.
6
+ export function hasDockerCompose(targetDir) {
7
+ return fs.existsSync(path.join(targetDir, 'docker-compose.yml')) ||
8
+ fs.existsSync(path.join(targetDir, 'docker-compose.yaml'));
9
+ }
10
+
11
+ // 2. Parse docker-compose.yml and normalize it into an array of services.
12
+ export function parseDockerCompose(targetDir) {
13
+ let composePath = path.join(targetDir, 'docker-compose.yml');
14
+ if (!fs.existsSync(composePath)) {
15
+ composePath = path.join(targetDir, 'docker-compose.yaml');
16
+ }
17
+
18
+ if (!fs.existsSync(composePath)) return null;
19
+
20
+ try {
21
+ const fileContents = fs.readFileSync(composePath, 'utf8');
22
+ const data = load(fileContents);
23
+
24
+ if (!data || !data.services) return null;
25
+
26
+ const services = [];
27
+
28
+ for (const [name, config] of Object.entries(data.services)) {
29
+ // Extract the container port (e.g., "8080:80" -> 80)
30
+ let exposedPort = null;
31
+ if (config.ports && config.ports.length > 0) {
32
+ // Handle different port formats like "3000" or "8000:8000" or "127.0.0.1:8001:8001"
33
+ const portMapping = config.ports[0].toString();
34
+ const parts = portMapping.split(':');
35
+ exposedPort = parseInt(parts[parts.length - 1].replace(/[^0-9]/g, ''), 10);
36
+ }
37
+
38
+ // Normalize environment variables from Array or Object
39
+ let envVars = {};
40
+ if (Array.isArray(config.environment)) {
41
+ config.environment.forEach(env => {
42
+ const [key, ...val] = env.split('=');
43
+ if (key) envVars[key] = val.join('=');
44
+ });
45
+ } else if (typeof config.environment === 'object') {
46
+ envVars = config.environment;
47
+ }
48
+
49
+ services.push({
50
+ name,
51
+ build: config.build || null,
52
+ image: config.image || null,
53
+ port: exposedPort,
54
+ command: config.command || null,
55
+ environment: envVars
56
+ });
57
+ }
58
+
59
+ return services;
60
+ } catch (e) {
61
+ console.error('⚠️ Failed to parse Docker Compose file:', e.message);
62
+ return null;
63
+ }
64
+ }
@@ -62,6 +62,60 @@ export async function generateTemplates(targetDir, config) {
62
62
  config.DB_ENV_VARS = '';
63
63
  }
64
64
 
65
+ // 3.3. Docker Compose Overrides & Sidecars
66
+ let composeWebEnvVars = [];
67
+ let extraContainersHCL = "";
68
+
69
+ if (config.DOCKER_COMPOSE && config.DOCKER_COMPOSE.length > 0) {
70
+ // Identify the main web service (the one with the exposed port)
71
+ const webService = config.DOCKER_COMPOSE.find(s => s.port) || config.DOCKER_COMPOSE[0];
72
+
73
+ // Extract Web Env Vars
74
+ if (webService.environment) {
75
+ for (const [key, val] of Object.entries(webService.environment)) {
76
+ composeWebEnvVars.push(`{ "name": "${key}", "value": "${val}" }`);
77
+ }
78
+ }
79
+
80
+ // Extract Web Command Override (only if Procfile hasn't already set it)
81
+ if (webService.command && !config.TASK_COMMAND) {
82
+ config.TASK_COMMAND = `command = ${JSON.stringify(typeof webService.command === 'string' ? webService.command.split(' ') : webService.command)}`;
83
+ }
84
+
85
+ // Process Sidecar Containers (e.g., Redis, Memcached)
86
+ const sidecars = config.DOCKER_COMPOSE.filter(s => s.name !== webService.name);
87
+ if (sidecars.length > 0) {
88
+ extraContainersHCL = sidecars.map(service => {
89
+ const sidecarEnv = Object.entries(service.environment || {})
90
+ .map(([k, v]) => `{ "name": "${k}", "value": "${String(v).replace(/"/g, '\\"')}" }`)
91
+ .join(',\n ');
92
+
93
+ const sidecarCmd = service.command ? `\n command = ${JSON.stringify(typeof service.command === 'string' ? service.command.split(' ') : service.command)}` : '';
94
+
95
+ return `,
96
+ {
97
+ name = "${service.name}"
98
+ image = "${service.image || 'alpine:latest'}"
99
+ essential = true
100
+ environment = [
101
+ ${sidecarEnv}
102
+ ]${sidecarCmd}
103
+ logConfiguration = {
104
+ logDriver = "awslogs"
105
+ options = {
106
+ "awslogs-group" = aws_cloudwatch_log_group.app_logs.name
107
+ "awslogs-region" = "${config.REGION}"
108
+ "awslogs-stream-prefix" = "ecs-${service.name}"
109
+ }
110
+ }
111
+ }`;
112
+ }).join('');
113
+ }
114
+ }
115
+
116
+ config.COMPOSE_WEB_ENV_VARS = composeWebEnvVars.length > 0 ? composeWebEnvVars.join(',\n ') + ',' : '';
117
+ config.EXTRA_CONTAINERS = extraContainersHCL;
118
+
65
119
  // 4. Configure AWS Secrets Manager Integration
66
120
  // Build the initial HCL map for AWS Secrets Manager
67
121
  let initialSecretMap = `{\n EXAMPLE_API_KEY = "replace_me_in_aws_console"`;
@@ -83,6 +83,7 @@ resource "aws_ecs_task_definition" "app" {
83
83
  essential = true
84
84
 
85
85
  environment = [
86
+ {{COMPOSE_WEB_ENV_VARS}}
86
87
  {{DB_ENV_VARS}}
87
88
  ]
88
89
 
@@ -117,7 +118,7 @@ resource "aws_ecs_task_definition" "app" {
117
118
  "awslogs-stream-prefix" = "ecs"
118
119
  }
119
120
  }
120
- }
121
+ }{{EXTRA_CONTAINERS}}
121
122
  ])
122
123
  }
123
124
 
package/release_notes.md DELETED
@@ -1,7 +0,0 @@
1
- # πŸ“ Architecture Overview & Vercel Example
2
-
3
- This patch release improves the documentation generated for end-users and adds the Vercel migration reference implementation to our ecosystem.
4
-
5
- ### πŸ“– What's New
6
- * **Template Architecture Overview:** The auto-generated `README.md` placed in user repositories now includes a high-level "Architecture Overview". This ensures developers understand the AWS topology (ECS Fargate, ALB, IAM OIDC, S3 State) they just provisioned before diving into deployment commands.
7
- * **Vercel Example Linked:** Officially linked the `deploy-stack-vercel-nextjs-example` repository in the main project README, providing users a direct reference for migrating edge routing (`vercel.json`) and Next.js standalone configurations to AWS.