grada-run 0.0.1 → 0.32.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.
Files changed (231) hide show
  1. package/.github/workflows/deploy-docs.yml +37 -0
  2. package/.github/workflows/iac-validation.yml +303 -0
  3. package/.github/workflows/publish.yml +68 -0
  4. package/.github/workflows/sync-bedrock-models.yml +57 -0
  5. package/.github/workflows/test.yml +43 -0
  6. package/.muserules +31 -0
  7. package/LICENSE +21 -0
  8. package/README.md +193 -3
  9. package/apps/docs/.astro/collections/docs.schema.json +644 -0
  10. package/apps/docs/.astro/content-assets.mjs +4 -0
  11. package/apps/docs/.astro/content-modules.mjs +4 -0
  12. package/apps/docs/.astro/content.d.ts +179 -0
  13. package/apps/docs/.astro/data-store.json +1 -0
  14. package/apps/docs/.astro/dev.json +14 -0
  15. package/apps/docs/.astro/settings.json +5 -0
  16. package/apps/docs/.astro/types.d.ts +2 -0
  17. package/apps/docs/astro.config.mjs +97 -0
  18. package/apps/docs/package.json +17 -0
  19. package/apps/docs/src/content/docs/adrs/0001-s3-native-state-locking.md +37 -0
  20. package/apps/docs/src/content/docs/adrs/0002-eject-mechanism-pure-iac.md +39 -0
  21. package/apps/docs/src/content/docs/adrs/0003-sync-ai-context-strategy.md +48 -0
  22. package/apps/docs/src/content/docs/adrs/0004-iac-driven-diagnostic-context.md +37 -0
  23. package/apps/docs/src/content/docs/adrs/0005-ecs-fargate-alb-runtime-target.md +38 -0
  24. package/apps/docs/src/content/docs/adrs/0006-github-oidc-no-stored-keys.md +37 -0
  25. package/apps/docs/src/content/docs/adrs/0007-framework-detection-with-fallback.md +37 -0
  26. package/apps/docs/src/content/docs/adrs/0008-secrets-names-in-git-values-in-aws.md +37 -0
  27. package/apps/docs/src/content/docs/adrs/0009-regenerate-with-backup-on-rerun.md +37 -0
  28. package/apps/docs/src/content/docs/adrs/0010-advisory-only-security-scans.md +37 -0
  29. package/apps/docs/src/content/docs/cli/add.md +84 -0
  30. package/apps/docs/src/content/docs/cli/apply.md +32 -0
  31. package/apps/docs/src/content/docs/cli/db.md +200 -0
  32. package/apps/docs/src/content/docs/cli/destroy.md +31 -0
  33. package/apps/docs/src/content/docs/cli/diagnose.md +37 -0
  34. package/apps/docs/src/content/docs/cli/doctor.md +28 -0
  35. package/apps/docs/src/content/docs/cli/domain.md +57 -0
  36. package/apps/docs/src/content/docs/cli/drift.md +40 -0
  37. package/apps/docs/src/content/docs/cli/eject.md +29 -0
  38. package/apps/docs/src/content/docs/cli/exec.md +49 -0
  39. package/apps/docs/src/content/docs/cli/gc.md +37 -0
  40. package/apps/docs/src/content/docs/cli/init.md +72 -0
  41. package/apps/docs/src/content/docs/cli/logs.md +39 -0
  42. package/apps/docs/src/content/docs/cli/rollback.md +51 -0
  43. package/apps/docs/src/content/docs/cli/secrets.md +73 -0
  44. package/apps/docs/src/content/docs/cli/sleep.md +53 -0
  45. package/apps/docs/src/content/docs/cli/status.md +34 -0
  46. package/apps/docs/src/content/docs/cli/sync-ai.md +27 -0
  47. package/apps/docs/src/content/docs/guides/architecture.md +87 -0
  48. package/apps/docs/src/content/docs/guides/aws-credentials.md +72 -0
  49. package/apps/docs/src/content/docs/guides/background-workers.md +45 -0
  50. package/apps/docs/src/content/docs/guides/cicd-pipeline.md +64 -0
  51. package/apps/docs/src/content/docs/guides/database-connections.md +64 -0
  52. package/apps/docs/src/content/docs/guides/docker-compose.md +37 -0
  53. package/apps/docs/src/content/docs/guides/dockerfiles.md +46 -0
  54. package/apps/docs/src/content/docs/guides/ephemeral-pr-previews.md +39 -0
  55. package/apps/docs/src/content/docs/guides/examples.md +50 -0
  56. package/apps/docs/src/content/docs/guides/frameworks.md +88 -0
  57. package/apps/docs/src/content/docs/guides/headless.md +75 -0
  58. package/apps/docs/src/content/docs/guides/quickstart.md +52 -0
  59. package/apps/docs/src/content/docs/guides/rerun-init.md +43 -0
  60. package/apps/docs/src/content/docs/guides/secrets-management.md +83 -0
  61. package/apps/docs/src/content/docs/guides/understanding-your-bill.md +63 -0
  62. package/apps/docs/src/content/docs/index.mdx +103 -0
  63. package/apps/docs/src/content/docs/migrations/astro-vercel-to-aws.md +55 -0
  64. package/apps/docs/src/content/docs/migrations/heroku-procfile-to-aws.md +41 -0
  65. package/apps/docs/src/content/docs/migrations/nextjs-vercel-to-aws.md +51 -0
  66. package/apps/docs/src/content/docs/migrations/sveltekit-vercel-to-aws.md +63 -0
  67. package/apps/docs/src/content/docs/roadmap.md +97 -0
  68. package/apps/docs/src/content/docs/testing-strategy.md +32 -0
  69. package/apps/docs/src/content.config.ts +7 -0
  70. package/apps/docs/src/custom.css +14 -0
  71. package/apps/docs/tsconfig.json +6 -0
  72. package/bin/cli.js +140 -0
  73. package/package.json +105 -6
  74. package/scripts/sync-bedrock-models.js +22 -0
  75. package/scripts/test-iac.js +261 -0
  76. package/specs/add-redis-sqs-bedrock.md +128 -0
  77. package/specs/add-storage-dynamodb.md +106 -0
  78. package/specs/bedrock-model-catalog.md +131 -0
  79. package/specs/ci-pipeline.md +17 -0
  80. package/specs/cost-transparency.md +115 -0
  81. package/specs/custom-domains-and-ses.md +153 -0
  82. package/specs/database-suite-expansion.md +151 -0
  83. package/specs/db-connect.md +69 -0
  84. package/specs/db-lifecycle-migrations.md +159 -0
  85. package/specs/dependency-aware-init.md +176 -0
  86. package/specs/deploy-stack-to-grada-run-rebrand.md +45 -0
  87. package/specs/deployment-safety.md +170 -0
  88. package/specs/diagnose.md +16 -0
  89. package/specs/docs-hub.md +16 -0
  90. package/specs/dx-polish.md +46 -0
  91. package/specs/exec.md +25 -0
  92. package/specs/finops-cron-drift.md +161 -0
  93. package/specs/gc.md +26 -0
  94. package/specs/integration-suite.md +16 -0
  95. package/specs/logs.md +32 -0
  96. package/specs/rollback-live-polling.md +40 -0
  97. package/specs/secrets-pull-audit.md +51 -0
  98. package/specs/serverless-lambda-target.md +133 -0
  99. package/specs/status.md +31 -0
  100. package/specs/telemetry-and-spawn-hardening.md +69 -0
  101. package/specs/telemetry-hardening.md +35 -0
  102. package/src/commands/add.js +1111 -0
  103. package/src/commands/apply.js +214 -0
  104. package/src/commands/db/backup.js +229 -0
  105. package/src/commands/db/connect.js +304 -0
  106. package/src/commands/db/enable-vector.js +344 -0
  107. package/src/commands/db/import.js +604 -0
  108. package/src/commands/db/migrate.js +477 -0
  109. package/src/commands/db/restore.js +361 -0
  110. package/src/commands/db.js +87 -0
  111. package/src/commands/destroy.js +217 -0
  112. package/src/commands/diagnose.js +460 -0
  113. package/src/commands/doctor.js +109 -0
  114. package/src/commands/domain.js +685 -0
  115. package/src/commands/drift.js +243 -0
  116. package/src/commands/eject.js +127 -0
  117. package/src/commands/exec.js +222 -0
  118. package/src/commands/gc.js +250 -0
  119. package/src/commands/init.js +649 -0
  120. package/src/commands/logs.js +256 -0
  121. package/src/commands/rollback.js +323 -0
  122. package/src/commands/secrets.js +485 -0
  123. package/src/commands/sleep.js +347 -0
  124. package/src/commands/status.js +309 -0
  125. package/src/commands/sync-ai.js +115 -0
  126. package/src/commands/wake.js +337 -0
  127. package/src/core/parser.js +126 -0
  128. package/src/core/telemetry.js +244 -0
  129. package/src/data/bedrock-models.json +896 -0
  130. package/src/utils/addons.js +126 -0
  131. package/src/utils/ai-rules.js +59 -0
  132. package/src/utils/args.js +91 -0
  133. package/src/utils/aws.js +178 -0
  134. package/src/utils/backup.js +69 -0
  135. package/src/utils/bedrock-catalog.js +511 -0
  136. package/src/utils/capabilities.js +500 -0
  137. package/src/utils/command.js +65 -0
  138. package/src/utils/db-tunnel.js +164 -0
  139. package/src/utils/detector.js +298 -0
  140. package/src/utils/dockerCompose.js +65 -0
  141. package/src/utils/domains.js +73 -0
  142. package/src/utils/ecs-runner.js +289 -0
  143. package/src/utils/ecs.js +92 -0
  144. package/src/utils/frameworks.js +55 -0
  145. package/src/utils/generator.js +527 -0
  146. package/src/utils/hcl.js +426 -0
  147. package/src/utils/lambda-ecr.js +185 -0
  148. package/src/utils/prompts.js +278 -0
  149. package/src/utils/rds.js +131 -0
  150. package/src/utils/resolvers.js +174 -0
  151. package/src/utils/sleep-state.js +140 -0
  152. package/src/utils/sleep-targets.js +139 -0
  153. package/src/utils/system.js +42 -0
  154. package/src/utils/terraform.js +70 -0
  155. package/src/utils/visualizer.js +381 -0
  156. package/src/utils/warnings.js +49 -0
  157. package/templates/README.md +150 -0
  158. package/templates/docker/django.Dockerfile +40 -0
  159. package/templates/docker/go.Dockerfile +23 -0
  160. package/templates/docker/nestjs.Dockerfile +33 -0
  161. package/templates/docker/nextjs.Dockerfile +55 -0
  162. package/templates/docker/node.Dockerfile +24 -0
  163. package/templates/docker/nuxt.Dockerfile +47 -0
  164. package/templates/docker/python.Dockerfile +38 -0
  165. package/templates/docker/rails.Dockerfile +59 -0
  166. package/templates/docker/static.Dockerfile +32 -0
  167. package/templates/docker/svelte.Dockerfile +52 -0
  168. package/templates/github/deploy-lambda.yml +120 -0
  169. package/templates/github/deploy.yml +138 -0
  170. package/templates/github/drift.yml +112 -0
  171. package/templates/github/preview-lambda.yml +86 -0
  172. package/templates/github/preview.yml +69 -0
  173. package/templates/github/teardown.yml +43 -0
  174. package/templates/terraform/addons/bedrock.tf +34 -0
  175. package/templates/terraform/addons/cron-lambda.tf +78 -0
  176. package/templates/terraform/addons/cron.tf +101 -0
  177. package/templates/terraform/addons/dynamodb.tf +73 -0
  178. package/templates/terraform/addons/redis.tf +64 -0
  179. package/templates/terraform/addons/s3.tf +143 -0
  180. package/templates/terraform/addons/ses.tf +73 -0
  181. package/templates/terraform/addons/sqs.tf +67 -0
  182. package/templates/terraform/backend.tf +22 -0
  183. package/templates/terraform/cloudfront-lambda.tf +80 -0
  184. package/templates/terraform/cloudfront.tf +80 -0
  185. package/templates/terraform/database-aurora-postgresql.tf +92 -0
  186. package/templates/terraform/database-mysql.tf +72 -0
  187. package/templates/terraform/database.tf +71 -0
  188. package/templates/terraform/main-lambda.tf +229 -0
  189. package/templates/terraform/main.tf +296 -0
  190. package/templates/terraform/network.tf +95 -0
  191. package/templates/terraform/oidc.tf +64 -0
  192. package/templates/terraform/secrets.tf +31 -0
  193. package/templates/terraform/worker.tf +69 -0
  194. package/tests/__snapshots__/generator.test.js.snap +9633 -0
  195. package/tests/add.test.js +2037 -0
  196. package/tests/ai.test.js +94 -0
  197. package/tests/apply.test.js +488 -0
  198. package/tests/args.test.js +86 -0
  199. package/tests/aws.test.js +244 -0
  200. package/tests/capabilities.test.js +307 -0
  201. package/tests/cli.test.js +29 -0
  202. package/tests/command.test.js +100 -0
  203. package/tests/commands-import.test.js +74 -0
  204. package/tests/db.test.js +2704 -0
  205. package/tests/destroy.test.js +391 -0
  206. package/tests/detector.test.js +79 -0
  207. package/tests/diagnose.test.js +779 -0
  208. package/tests/doctor.test.js +202 -0
  209. package/tests/domain.test.js +899 -0
  210. package/tests/drift.test.js +243 -0
  211. package/tests/ecs.test.js +130 -0
  212. package/tests/eject.test.js +65 -0
  213. package/tests/exec.test.js +380 -0
  214. package/tests/gc.test.js +496 -0
  215. package/tests/generator.test.js +794 -0
  216. package/tests/headless.test.js +562 -0
  217. package/tests/lambda-ecr.test.js +185 -0
  218. package/tests/logs.test.js +447 -0
  219. package/tests/parser.test.js +160 -0
  220. package/tests/rds.test.js +244 -0
  221. package/tests/resolvers.test.js +282 -0
  222. package/tests/rollback.test.js +692 -0
  223. package/tests/secrets.test.js +752 -0
  224. package/tests/sleep-wake.test.js +1016 -0
  225. package/tests/status.test.js +370 -0
  226. package/tests/system.test.js +70 -0
  227. package/tests/telemetry.test.js +520 -0
  228. package/tests/terraform.test.js +84 -0
  229. package/tests/visualizer.test.js +496 -0
  230. package/vitest.config.js +9 -0
  231. package/index.js +0 -2
@@ -0,0 +1,33 @@
1
+ # --- Stage 1: Build ---
2
+ FROM node:22-alpine AS builder
3
+ WORKDIR /app
4
+ COPY package*.json ./
5
+ RUN npm ci
6
+ COPY . .
7
+ RUN npm run build
8
+
9
+ # --- Stage 2: Production ---
10
+ FROM node:22-alpine
11
+
12
+ # 1. DevSecOps: Patch Alpine OS
13
+ RUN apk update && apk upgrade --no-cache
14
+
15
+ ENV NODE_ENV=production
16
+ WORKDIR /app
17
+
18
+ # 2. Install ONLY production dependencies
19
+ COPY --chown=node:node package*.json ./
20
+ RUN npm ci --omit=dev && npm cache clean --force
21
+
22
+ # 3. DevSecOps: Nuke all package managers to eliminate base-image CVEs
23
+ RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \
24
+ /opt/yarn-* /usr/local/bin/yarn /usr/local/bin/yarnpkg \
25
+ /usr/local/lib/node_modules/corepack /usr/local/bin/corepack
26
+
27
+ # 4. Copy the compiled application
28
+ COPY --chown=node:node --from=builder /app/dist ./dist
29
+
30
+ USER node
31
+ # Expose the port defined by Terraform
32
+ EXPOSE {{PORT}}
33
+ CMD ["node", "dist/main.js"]
@@ -0,0 +1,55 @@
1
+ # Stage 1: Install dependencies and build the app
2
+ FROM node:22-alpine AS builder
3
+ WORKDIR /app
4
+
5
+ # FIX 1: Upgrade Alpine system packages & upgrade global NPM to patch 'tar' and 'pacote' CVEs
6
+ RUN apk upgrade --no-cache && \
7
+ npm install -g npm@latest
8
+
9
+ # Copy package files and install dependencies
10
+ COPY package.json package-lock.json* ./
11
+ RUN npm ci
12
+
13
+ # Copy the rest of the application code
14
+ COPY . .
15
+
16
+ # Build the Next.js application
17
+ # (This requires output: 'standalone' in next.config.ts)
18
+ RUN npm run build
19
+
20
+ # Stage 2: Production environment
21
+ FROM node:22-alpine AS runner
22
+ WORKDIR /app
23
+
24
+ # FIX 2: Upgrade Alpine packages and absolutely destroy npm, yarn, and corepack
25
+ # to eliminate all remaining Critical/High container vulnerabilities.
26
+ RUN apk upgrade --no-cache && \
27
+ rm -rf /usr/local/lib/node_modules/npm \
28
+ /usr/local/bin/npm \
29
+ /usr/local/bin/npx \
30
+ /opt/yarn-* \
31
+ /usr/local/bin/yarn \
32
+ /usr/local/bin/yarnpkg \
33
+ /usr/local/lib/node_modules/corepack \
34
+ /usr/local/bin/corepack
35
+
36
+ ENV NODE_ENV=production
37
+ ENV PORT={{PORT}}
38
+ ENV HOSTNAME="0.0.0.0"
39
+
40
+ # Create an unprivileged user and group
41
+ RUN addgroup -g 1001 -S nodejs && \
42
+ adduser -S nextjs -u 1001 -G nodejs
43
+
44
+ # Copy the standalone output and assign ownership to the unprivileged user
45
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
46
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
47
+ COPY --from=builder --chown=nextjs:nodejs /app/public ./public
48
+
49
+ # Switch to the unprivileged user before executing
50
+ USER nextjs
51
+
52
+ EXPOSE {{PORT}}
53
+
54
+ # Start the standalone Node.js server
55
+ CMD ["node", "server.js"]
@@ -0,0 +1,24 @@
1
+ FROM node:22-alpine
2
+
3
+ # 1. DevSecOps: Patch underlying Alpine OS vulnerabilities and update global npm
4
+ RUN apk update && apk upgrade --no-cache && \
5
+ npm install -g npm@latest
6
+
7
+ # 2. Set production environment (optimizes Node and prevents dev dependencies)
8
+ ENV NODE_ENV=production
9
+
10
+ WORKDIR /app
11
+
12
+ # 3. Copy dependency manifests with non-root ownership
13
+ COPY --chown=node:node package*.json ./
14
+ RUN npm ci --omit=dev
15
+
16
+ # 4. Copy application code with non-root ownership
17
+ COPY --chown=node:node . .
18
+
19
+ # 5. DevSecOps best practice: do not run the container as root
20
+ USER node
21
+
22
+ EXPOSE {{PORT}}
23
+
24
+ CMD ["npm", "start"]
@@ -0,0 +1,47 @@
1
+ # Stage 1: Build the Nuxt Nitro output
2
+ FROM node:22-alpine AS builder
3
+ WORKDIR /app
4
+
5
+ # Install native build tools required to compile C++ Node modules (like better-sqlite3)
6
+ RUN apk update && \
7
+ apk add --no-cache python3 make g++ sqlite-dev
8
+
9
+ COPY package.json package-lock.json* ./
10
+ RUN npm ci
11
+
12
+ # Explicitly install better-sqlite3 to satisfy Nuxt 4 / Nitro dynamic requirements
13
+ RUN npm install better-sqlite3
14
+
15
+ COPY . .
16
+ RUN npm run build
17
+
18
+ # Stage 2: Production runner
19
+ FROM node:22-alpine AS runner
20
+ WORKDIR /app
21
+
22
+ ENV NODE_ENV=production
23
+ ENV PORT={{PORT}}
24
+ ENV HOSTNAME="0.0.0.0"
25
+
26
+ # 1. Upgrade Alpine OS packages to clear OpenSSL/crypto CVEs
27
+ # 2. Vaporize Node package managers (npm, yarn, corepack) to clear ghost CVEs
28
+ RUN apk update && apk upgrade --no-cache && \
29
+ rm -rf /usr/local/lib/node_modules \
30
+ /usr/local/bin/npm \
31
+ /usr/local/bin/npx \
32
+ /usr/local/bin/yarn \
33
+ /usr/local/bin/yarnpkg \
34
+ /usr/local/bin/corepack \
35
+ /opt/yarn-*
36
+
37
+ # Create an unprivileged user and group
38
+ RUN addgroup -g 1001 -S nodejs && \
39
+ adduser -S nuxtjs -u 1001 -G nodejs
40
+
41
+ # Copy the standalone output and assign ownership
42
+ COPY --from=builder --chown=nuxtjs:nodejs /app/.output ./.output
43
+
44
+ USER nuxtjs
45
+ EXPOSE {{PORT}}
46
+
47
+ CMD ["node", ".output/server/index.mjs"]
@@ -0,0 +1,38 @@
1
+ FROM python:3.12-alpine
2
+
3
+ # Prevent Python from writing .pyc files and buffer stdout for cleaner logs
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+
7
+ WORKDIR /app
8
+
9
+ # Create a non-root user for security compliance (Alpine syntax)
10
+ RUN addgroup -S appuser && \
11
+ adduser -S appuser -G appuser -D -s /bin/sh
12
+
13
+ # Install runtime libraries and temporary build tools
14
+ RUN apk update && apk upgrade --no-cache && \
15
+ apk add --no-cache libpq && \
16
+ apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev
17
+
18
+ COPY requirements.txt .
19
+
20
+ # Upgrade pip, install dependencies, clear caches, and NUKE package managers
21
+ RUN pip install --no-cache-dir --upgrade pip setuptools wheel && \
22
+ pip install --no-cache-dir -r requirements.txt && \
23
+ find / -type d -name "ensurepip" -exec rm -rf {} + || true && \
24
+ rm -rf /root/.cache/pip && \
25
+ pip uninstall -y setuptools wheel pip
26
+
27
+ # Remove the build tools to shrink the image and reduce attack surface
28
+ RUN apk del .build-deps
29
+
30
+ # Copy with ownership
31
+ COPY --chown=appuser:appuser . .
32
+
33
+ # Drop root privileges
34
+ USER appuser
35
+
36
+ EXPOSE {{PORT}}
37
+
38
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "{{PORT}}"]
@@ -0,0 +1,59 @@
1
+ # Stage 1: Build the Rails application
2
+ FROM ruby:3.3.5-alpine AS builder
3
+ WORKDIR /app
4
+
5
+ # Install native build tools required to compile C extensions (like pg or nokogiri)
6
+ RUN apk update && \
7
+ apk add --no-cache build-base postgresql-dev tzdata nodejs yarn
8
+
9
+ COPY Gemfile Gemfile.lock* ./
10
+
11
+ # Use ENV to guarantee Bundler skips dev/test gems
12
+ ENV BUNDLE_WITHOUT="development:test"
13
+
14
+ # Install deps and remove cache
15
+ RUN bundle install && \
16
+ rm -rf /usr/local/bundle/cache/*.gem
17
+
18
+ COPY . .
19
+
20
+ # Precompile assets (we use a dummy key since it's just for building)
21
+ RUN SECRET_KEY_BASE=dummy bundle exec rails assets:precompile || true
22
+
23
+ # Stage 2: Production runner
24
+ FROM ruby:3.3.5-alpine AS runner
25
+ WORKDIR /app
26
+
27
+ ENV RAILS_ENV=production \
28
+ RAILS_SERVE_STATIC_FILES=true \
29
+ RAILS_LOG_TO_STDOUT=true \
30
+ BUNDLE_WITHOUT="development:test" \
31
+ PORT={{PORT}}
32
+
33
+ # Upgrade Alpine OS to patch system CVEs and install runtime libs
34
+ # Explicitly patch Ruby's default gems and remove their legacy gemspecs so Trivy ignores them
35
+ RUN apk update && apk upgrade --no-cache && \
36
+ apk add --no-cache postgresql-libs tzdata && \
37
+ apk add --no-cache --virtual .build-deps build-base zlib-dev && \
38
+ gem install erb net-imap resolv rexml uri zlib && \
39
+ rm -f /usr/local/lib/ruby/gems/*/specifications/default/erb-*.gemspec \
40
+ /usr/local/lib/ruby/gems/*/specifications/default/resolv-*.gemspec \
41
+ /usr/local/lib/ruby/gems/*/specifications/default/uri-*.gemspec \
42
+ /usr/local/lib/ruby/gems/*/specifications/default/zlib-*.gemspec \
43
+ /usr/local/lib/ruby/gems/*/specifications/net-imap-0.4.*.gemspec \
44
+ /usr/local/lib/ruby/gems/*/specifications/rexml-3.3.6.gemspec && \
45
+ apk del .build-deps && \
46
+ rm -rf /var/cache/apk/*
47
+
48
+ # Create unprivileged user
49
+ RUN addgroup -g 1001 -S railsgroup && \
50
+ adduser -S railsuser -u 1001 -G railsgroup
51
+
52
+ # Copy built gems and application code
53
+ COPY --from=builder --chown=railsuser:railsgroup /usr/local/bundle /usr/local/bundle
54
+ COPY --from=builder --chown=railsuser:railsgroup /app /app
55
+
56
+ USER railsuser
57
+ EXPOSE {{PORT}}
58
+
59
+ CMD ["bundle", "exec", "puma", "-b", "tcp://0.0.0.0:{{PORT}}"]
@@ -0,0 +1,32 @@
1
+ # STAGE 1: Build the static assets
2
+ FROM node:22-alpine AS builder
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+ # Use clean install for reliable, reproducible builds
7
+ RUN npm ci
8
+
9
+ COPY . .
10
+ # Runs the standard build script defined in package.json
11
+ RUN npm run build
12
+
13
+ # STAGE 2: Serve with Hardened Nginx
14
+ FROM nginxinc/nginx-unprivileged:alpine
15
+
16
+ # Adjusts BUILD_DIR to match your framework's output folder
17
+ COPY --from=builder /app/{{BUILD_DIR}} /usr/share/nginx/html
18
+
19
+ # Inject custom Nginx configuration for unprivileged ports and SPA routing
20
+ RUN echo "server {" > /etc/nginx/conf.d/default.conf && \
21
+ echo " listen {{PORT}};" >> /etc/nginx/conf.d/default.conf && \
22
+ echo " listen [::]:{{PORT}};" >> /etc/nginx/conf.d/default.conf && \
23
+ echo " server_name localhost;" >> /etc/nginx/conf.d/default.conf && \
24
+ echo " location / {" >> /etc/nginx/conf.d/default.conf && \
25
+ echo " root /usr/share/nginx/html;" >> /etc/nginx/conf.d/default.conf && \
26
+ echo " index index.html index.htm;" >> /etc/nginx/conf.d/default.conf && \
27
+ echo " try_files \$uri \$uri/ /index.html;" >> /etc/nginx/conf.d/default.conf && \
28
+ echo " }" >> /etc/nginx/conf.d/default.conf && \
29
+ echo "}" >> /etc/nginx/conf.d/default.conf
30
+
31
+ EXPOSE {{PORT}}
32
+ CMD ["nginx", "-g", "daemon off;"]
@@ -0,0 +1,52 @@
1
+ # ==========================================
2
+ # Stage 1: Builder
3
+ # ==========================================
4
+ FROM node:22-alpine AS builder
5
+ WORKDIR /app
6
+
7
+ # Install all dependencies (including devDependencies)
8
+ COPY package*.json ./
9
+ RUN npm ci
10
+
11
+ # Copy source code
12
+ COPY . .
13
+
14
+ # ZERO-CLICK MAGIC: Automatically inject adapter-node if the user left adapter-auto in their config.
15
+ # This ensures the build/ directory is always generated without requiring manual code changes.
16
+ RUN npm install -D @sveltejs/adapter-node@latest && \
17
+ sed -i 's/@sveltejs\/adapter-auto/@sveltejs\/adapter-node/g' svelte.config.js 2>/dev/null || true && \
18
+ sed -i 's/@sveltejs\/adapter-auto/@sveltejs\/adapter-node/g' vite.config.ts 2>/dev/null || true && \
19
+ sed -i 's/@sveltejs\/adapter-auto/@sveltejs\/adapter-node/g' vite.config.js 2>/dev/null || true
20
+
21
+ # Inject the bypass flag and compile the SvelteKit application
22
+ RUN GRADA_BYPASS=true npm run build
23
+
24
+ # ==========================================
25
+ # Stage 2: Production (Zero-CVE)
26
+ # ==========================================
27
+ FROM node:22-alpine
28
+
29
+ # 1. DevSecOps: Patch underlying Alpine OS vulnerabilities
30
+ RUN apk update && apk upgrade --no-cache
31
+
32
+ # 2. Set production environment
33
+ ENV NODE_ENV=production
34
+ WORKDIR /app
35
+
36
+ # 3. Copy manifests and install ONLY production dependencies
37
+ COPY --from=builder --chown=node:node /app/package*.json ./
38
+ RUN npm ci --omit=dev && npm cache clean --force
39
+
40
+ # 4. Copy the compiled SvelteKit server from the builder stage
41
+ COPY --from=builder --chown=node:node /app/build/ ./build/
42
+
43
+ # 5. DevSecOps: Nuke all package managers to eliminate base-image CVEs
44
+ RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx \
45
+ /opt/yarn-* /usr/local/bin/yarn /usr/local/bin/yarnpkg \
46
+ /usr/local/lib/node_modules/corepack /usr/local/bin/corepack
47
+
48
+ USER node
49
+ EXPOSE {{PORT}}
50
+
51
+ # 6. Execute the raw Node server directly
52
+ CMD ["node", "build/index.js"]
@@ -0,0 +1,120 @@
1
+ name: Deploy to AWS Lambda
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - {{DEPLOY_BRANCH}}
7
+ schedule:
8
+ - cron: '0 0 * * 0'
9
+
10
+ env:
11
+ AWS_REGION: {{REGION}}
12
+ ECR_REPOSITORY: {{PROJECT_NAME}}-repo
13
+ LAMBDA_FUNCTION: {{PROJECT_NAME}}-fn
14
+
15
+ permissions:
16
+ id-token: write
17
+ contents: read
18
+
19
+ jobs:
20
+ deploy:
21
+ name: Build & Deploy
22
+ runs-on: ubuntu-latest
23
+
24
+ steps:
25
+ - name: Checkout Code
26
+ uses: actions/checkout@v4
27
+
28
+ # --- 1. IaC SECURITY SCAN ---
29
+ - name: Scan Terraform for Misconfigurations
30
+ uses: aquasecurity/trivy-action@master
31
+ with:
32
+ scan-type: 'fs'
33
+ scan-ref: 'terraform/'
34
+ scanners: 'vuln,secret,misconfig'
35
+ format: 'table'
36
+ exit-code: '0' # Informational only, will not break the build
37
+ severity: 'CRITICAL,HIGH'
38
+ output: 'trivy-iac-summary.txt'
39
+
40
+ - name: Publish IaC Summary
41
+ if: always()
42
+ run: |
43
+ if [ -f trivy-iac-summary.txt ]; then
44
+ echo "### 🏗️ Terraform Misconfiguration Scan" >> $GITHUB_STEP_SUMMARY
45
+ echo '```' >> $GITHUB_STEP_SUMMARY
46
+ cat trivy-iac-summary.txt >> $GITHUB_STEP_SUMMARY
47
+ echo '```' >> $GITHUB_STEP_SUMMARY
48
+ fi
49
+
50
+ # --- 2. INFRASTRUCTURE SYNC (The New Marketplace Action) ---
51
+ - name: Apply Infrastructure Changes
52
+ uses: grada-run/grada-action@v1
53
+ with:
54
+ aws-region: ${{ env.AWS_REGION }}
55
+ role-to-assume: arn:aws:iam::{{AWS_ACCOUNT_ID}}:role/{{PROJECT_NAME}}-github-actions-role
56
+ terraform-dir: 'terraform'
57
+
58
+ # --- 3. BUILD & PUSH ---
59
+ - name: Login to Amazon ECR
60
+ id: login-ecr
61
+ uses: aws-actions/amazon-ecr-login@v2
62
+
63
+ - name: Build Docker image
64
+ id: build-image
65
+ env:
66
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
67
+ IMAGE_TAG: latest
68
+ run: |
69
+ SHA_TAG=${GITHUB_SHA::7}
70
+ # The Lambda function runs on x86_64 (see terraform/main.tf), so the
71
+ # image must be built for linux/amd64 even on arm64 runners.
72
+ docker build --platform linux/amd64 -t $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG .
73
+ docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
74
+
75
+ # --- 4. CONTAINER SECURITY SCAN ---
76
+ - name: Scan Container for Vulnerabilities (SARIF Output)
77
+ uses: aquasecurity/trivy-action@master
78
+ with:
79
+ image-ref: '${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest'
80
+ format: 'table'
81
+ output: 'trivy-container-summary.txt'
82
+ exit-code: '0' # Informational only, will not break the build
83
+ ignore-unfixed: true
84
+ vuln-type: 'os,library'
85
+ severity: 'CRITICAL,HIGH'
86
+
87
+ - name: Publish Container Summary
88
+ if: always()
89
+ run: |
90
+ if [ -f trivy-container-summary.txt ]; then
91
+ echo "### 🛡️ Container Security Scan Results" >> $GITHUB_STEP_SUMMARY
92
+ echo '```' >> $GITHUB_STEP_SUMMARY
93
+ cat trivy-container-summary.txt >> $GITHUB_STEP_SUMMARY
94
+ echo '```' >> $GITHUB_STEP_SUMMARY
95
+ fi
96
+
97
+ # --- 5. DEPLOY ---
98
+ - name: Push image to Amazon ECR
99
+ env:
100
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
101
+ IMAGE_TAG: latest
102
+ run: |
103
+ SHA_TAG=${GITHUB_SHA::7}
104
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG
105
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
106
+ echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG" >> $GITHUB_OUTPUT
107
+
108
+ # Each code push deploys the immutable SHA-tagged image to the Lambda
109
+ # function, so every ECR tag stays a redeployable rollback point (and
110
+ # `latest` is never the deploy artifact of record).
111
+ - name: Deploy image to AWS Lambda
112
+ run: |
113
+ IMAGE_URI=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${GITHUB_SHA::7}
114
+ aws lambda update-function-code \
115
+ --function-name ${{ env.LAMBDA_FUNCTION }} \
116
+ --image-uri "$IMAGE_URI" \
117
+ --region ${{ env.AWS_REGION }}
118
+ aws lambda wait function-updated \
119
+ --function-name ${{ env.LAMBDA_FUNCTION }} \
120
+ --region ${{ env.AWS_REGION }}
@@ -0,0 +1,138 @@
1
+ name: Deploy to AWS ECS
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - {{DEPLOY_BRANCH}}
7
+ schedule:
8
+ - cron: '0 0 * * 0'
9
+
10
+ env:
11
+ AWS_REGION: {{REGION}}
12
+ ECR_REPOSITORY: {{PROJECT_NAME}}-repo
13
+ ECS_CLUSTER: {{PROJECT_NAME}}-cluster
14
+ ECS_SERVICE: {{PROJECT_NAME}}-service
15
+ ECS_TASK_FAMILY: {{PROJECT_NAME}}-task
16
+
17
+ permissions:
18
+ id-token: write
19
+ contents: read
20
+
21
+ jobs:
22
+ deploy:
23
+ name: Build & Deploy
24
+ runs-on: ubuntu-latest
25
+
26
+ steps:
27
+ - name: Checkout Code
28
+ uses: actions/checkout@v4
29
+
30
+ # --- 1. IaC SECURITY SCAN ---
31
+ - name: Scan Terraform for Misconfigurations
32
+ uses: aquasecurity/trivy-action@master
33
+ with:
34
+ scan-type: 'fs'
35
+ scan-ref: 'terraform/'
36
+ scanners: 'vuln,secret,misconfig'
37
+ format: 'table'
38
+ exit-code: '0' # Informational only, will not break the build
39
+ severity: 'CRITICAL,HIGH'
40
+ output: 'trivy-iac-summary.txt'
41
+
42
+ - name: Publish IaC Summary
43
+ if: always()
44
+ run: |
45
+ if [ -f trivy-iac-summary.txt ]; then
46
+ echo "### 🏗️ Terraform Misconfiguration Scan" >> $GITHUB_STEP_SUMMARY
47
+ echo '```' >> $GITHUB_STEP_SUMMARY
48
+ cat trivy-iac-summary.txt >> $GITHUB_STEP_SUMMARY
49
+ echo '```' >> $GITHUB_STEP_SUMMARY
50
+ fi
51
+
52
+ # --- 2. INFRASTRUCTURE SYNC (The New Marketplace Action) ---
53
+ - name: Apply Infrastructure Changes
54
+ uses: grada-run/grada-action@v1
55
+ with:
56
+ aws-region: ${{ env.AWS_REGION }}
57
+ role-to-assume: arn:aws:iam::{{AWS_ACCOUNT_ID}}:role/{{PROJECT_NAME}}-github-actions-role
58
+ terraform-dir: 'terraform'
59
+
60
+ # --- 3. BUILD & PUSH ---
61
+ - name: Login to Amazon ECR
62
+ id: login-ecr
63
+ uses: aws-actions/amazon-ecr-login@v2
64
+
65
+ - name: Build Docker image
66
+ id: build-image
67
+ env:
68
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
69
+ IMAGE_TAG: latest
70
+ run: |
71
+ SHA_TAG=${GITHUB_SHA::7}
72
+ docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG .
73
+ docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
74
+
75
+ # --- 4. CONTAINER SECURITY SCAN ---
76
+ - name: Scan Container for Vulnerabilities (SARIF Output)
77
+ uses: aquasecurity/trivy-action@master
78
+ with:
79
+ image-ref: '${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest'
80
+ format: 'table'
81
+ output: 'trivy-container-summary.txt'
82
+ exit-code: '0' # Informational only, will not break the build
83
+ ignore-unfixed: true
84
+ vuln-type: 'os,library'
85
+ severity: 'CRITICAL,HIGH'
86
+
87
+ - name: Publish Container Summary
88
+ if: always()
89
+ run: |
90
+ if [ -f trivy-container-summary.txt ]; then
91
+ echo "### 🛡️ Container Security Scan Results" >> $GITHUB_STEP_SUMMARY
92
+ echo '```' >> $GITHUB_STEP_SUMMARY
93
+ cat trivy-container-summary.txt >> $GITHUB_STEP_SUMMARY
94
+ echo '```' >> $GITHUB_STEP_SUMMARY
95
+ fi
96
+
97
+ # --- 5. DEPLOY ---
98
+ - name: Push image to Amazon ECR
99
+ env:
100
+ ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
101
+ IMAGE_TAG: latest
102
+ run: |
103
+ SHA_TAG=${GITHUB_SHA::7}
104
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG
105
+ docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
106
+ echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$SHA_TAG" >> $GITHUB_OUTPUT
107
+
108
+ # Each code push registers a new task definition revision pinned to the
109
+ # immutable SHA-tagged image, so `rollback` always has history to
110
+ # return to (and `latest` is never overwritten in place as the deploy
111
+ # artifact of record).
112
+ - name: Register new task definition revision
113
+ id: register-task-def
114
+ run: |
115
+ IMAGE_URI=${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${GITHUB_SHA::7}
116
+ TASK_DEF=$(aws ecs describe-task-definition \
117
+ --task-definition ${{ env.ECS_TASK_FAMILY }} \
118
+ --region ${{ env.AWS_REGION }} \
119
+ --query 'taskDefinition' \
120
+ --output json)
121
+ NEW_TASK_DEF=$(echo "$TASK_DEF" | jq \
122
+ --arg IMAGE "$IMAGE_URI" \
123
+ '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy, .deregisteredAt)')
124
+ NEW_TASK_ARN=$(aws ecs register-task-definition \
125
+ --region ${{ env.AWS_REGION }} \
126
+ --cli-input-json "$NEW_TASK_DEF" \
127
+ --query 'taskDefinition.taskDefinitionArn' \
128
+ --output text)
129
+ echo "task-arn=$NEW_TASK_ARN" >> $GITHUB_OUTPUT
130
+
131
+ - name: Force ECS deployment
132
+ run: |
133
+ aws ecs update-service \
134
+ --cluster ${{ env.ECS_CLUSTER }} \
135
+ --service ${{ env.ECS_SERVICE }} \
136
+ --task-definition ${{ steps.register-task-def.outputs.task-arn }} \
137
+ --force-new-deployment \
138
+ --region ${{ env.AWS_REGION }}