deploy-stack 0.2.10 → 0.3.1
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/package.json +1 -1
- package/src/commands/init.js +10 -2
- package/src/utils/detector.js +1 -1
- package/src/utils/warnings.js +13 -2
- package/templates/README.md +7 -1
- package/templates/docker/static.Dockerfile +30 -6
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -232,10 +232,16 @@ export async function mainStack() {
|
|
|
232
232
|
// 9. Provide the Outro, Framework Warnings and Next Steps
|
|
233
233
|
const frameworkWarnings = getFrameworkWarning(finalFramework);
|
|
234
234
|
|
|
235
|
+
const isGitInitialized = fsSync.existsSync(path.join(targetDir, '.git'));
|
|
236
|
+
|
|
235
237
|
const cdStep = projectName === '.' ? '' : `1. cd ${projectName}\n `;
|
|
236
238
|
const deployStepNum = projectName === '.' ? '1' : '2';
|
|
237
239
|
const gitStepNum = projectName === '.' ? '2' : '3';
|
|
238
240
|
|
|
241
|
+
const gitInstructions = isGitInitialized
|
|
242
|
+
? `git add .\n git commit -m "chore: add AWS infrastructure and CI/CD"\n git push`
|
|
243
|
+
: `git init\n git add .\n git commit -m "chore: add AWS infrastructure and CI/CD"\n git branch -M main\n git remote add origin https://github.com/your-username/your-repo.git\n git push -u origin main`;
|
|
244
|
+
|
|
239
245
|
outro(`
|
|
240
246
|
${color.green('✅ Project provisioned successfully!')}
|
|
241
247
|
|
|
@@ -244,8 +250,10 @@ export async function mainStack() {
|
|
|
244
250
|
Next steps:
|
|
245
251
|
${cdStep}${deployStepNum}. Deploy infrastructure:
|
|
246
252
|
cd terraform && terraform init && terraform apply
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
|
|
254
|
+
${gitStepNum}. Push to GitHub to trigger CI/CD:
|
|
255
|
+
cd ..
|
|
256
|
+
${gitInstructions}
|
|
249
257
|
|
|
250
258
|
${color.cyan('Once deployed, Terraform will output your new https://*.cloudfront.net URL.')}
|
|
251
259
|
|
package/src/utils/detector.js
CHANGED
|
@@ -13,7 +13,7 @@ export function detectFramework(targetDir) {
|
|
|
13
13
|
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
14
14
|
|
|
15
15
|
if (deps['next']) return { id: 'nextjs', name: 'Next.js' };
|
|
16
|
-
if (deps['gatsby'] || deps['react-scripts'] || deps['vue']) return { id: 'static', name: 'Static Site' };
|
|
16
|
+
if (deps['vite'] || deps['astro'] || deps['@sveltejs/kit'] || deps['gatsby'] || deps['react-scripts'] || deps['@vue/cli-service']) return { id: 'static', name: 'Static Site (Vite, Astro, React)' };
|
|
17
17
|
if (deps['express']) return { id: 'node', name: 'Node.js / Express' };
|
|
18
18
|
} catch (e) {
|
|
19
19
|
// Silently fail if package.json is malformed
|
package/src/utils/warnings.js
CHANGED
|
@@ -15,10 +15,21 @@ export function getFrameworkWarning(frameworkId) {
|
|
|
15
15
|
color.yellow('\n 2. Your app must listen on 0.0.0.0 (not localhost) to receive traffic in Docker.\n\n')
|
|
16
16
|
);
|
|
17
17
|
case 'python':
|
|
18
|
-
return
|
|
18
|
+
return (
|
|
19
|
+
color.bgYellow(color.black(' ⚠️ IMPORTANT: PYTHON SETUP REQUIRED ')) +
|
|
19
20
|
color.yellow('\n 1. Ensure your requirements.txt includes your web framework (e.g., fastapi, uvicorn).') +
|
|
20
21
|
color.yellow('\n 2. Your app must listen on 0.0.0.0 (not localhost) to receive traffic in Docker.') +
|
|
21
|
-
color.yellow('\n 3. Ensure your app has a health check route returning 200 OK.\n\n')
|
|
22
|
+
color.yellow('\n 3. Ensure your app has a health check route returning 200 OK.\n\n')
|
|
23
|
+
);
|
|
24
|
+
case 'static':
|
|
25
|
+
return (
|
|
26
|
+
color.bgYellow(color.black(' ⚠️ IMPORTANT: STATIC SITE SETUP REQUIRED ')) +
|
|
27
|
+
color.yellow('\n 1. Open your generated Dockerfile.') +
|
|
28
|
+
color.yellow('\n 2. Ensure the build output folder on line 15 matches your framework:') +
|
|
29
|
+
color.yellow('\n Vite / Astro: COPY --from=builder /app/dist /usr/share/nginx/html') +
|
|
30
|
+
color.yellow('\n Create React App: COPY --from=builder /app/build /usr/share/nginx/html') +
|
|
31
|
+
color.yellow('\n 3. Ensure your package.json has a "build" script (e.g., "vite build").\n\n')
|
|
32
|
+
);
|
|
22
33
|
default:
|
|
23
34
|
return '';
|
|
24
35
|
}
|
package/templates/README.md
CHANGED
|
@@ -92,4 +92,10 @@ When running inside a Docker container, your server must bind to all network int
|
|
|
92
92
|
|
|
93
93
|
Make sure your app is configured correctly:
|
|
94
94
|
* **Express.js:** `app.listen(port, '0.0.0.0', () => ...)`
|
|
95
|
-
* **FastAPI:** `uvicorn.run(app, host="0.0.0.0", port=8000)`
|
|
95
|
+
* **FastAPI:** `uvicorn.run(app, host="0.0.0.0", port=8000)`
|
|
96
|
+
|
|
97
|
+
### 4. Static Sites (Vite, Astro, React, Vue)
|
|
98
|
+
|
|
99
|
+
If you are deploying a static site, your application is served via a highly optimized, unprivileged Nginx container.
|
|
100
|
+
1. **Build Folder:** Different frameworks output compiled assets to different folders. Open your `Dockerfile` and ensure the `COPY --from=builder` command points to the correct folder (`dist`, `build`, or `out`).
|
|
101
|
+
2. **Health Checks:** You do not need to configure a custom `/health` route. Nginx will automatically return a `200 OK` when AWS pings the root `/` index page.
|
|
@@ -1,13 +1,37 @@
|
|
|
1
|
+
# STAGE 1: Build the static assets
|
|
2
|
+
FROM node:20-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
|
|
1
14
|
FROM nginx:alpine
|
|
2
15
|
|
|
3
|
-
#
|
|
4
|
-
|
|
16
|
+
# ⚠️ CRITICAL: Adjust 'dist' to match your framework's output folder!
|
|
17
|
+
# Vite/Astro = dist | Create React App/Gatsby = build | Next.js Static = out
|
|
18
|
+
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
19
|
+
|
|
20
|
+
# Dynamically update the Nginx port
|
|
21
|
+
RUN sed -i "s/listen 80;/listen {{PORT}};/g" /etc/nginx/conf.d/default.conf
|
|
22
|
+
|
|
23
|
+
# Silence unprivileged user directive warning in main config
|
|
24
|
+
RUN sed -i 's/^user\s\+nginx;/# user nginx;/' /etc/nginx/nginx.conf
|
|
5
25
|
|
|
6
|
-
#
|
|
7
|
-
|
|
26
|
+
# DevSecOps Hardening: Drop root privileges for the Nginx process
|
|
27
|
+
RUN chown -R nginx:nginx /usr/share/nginx/html && \
|
|
28
|
+
chown -R nginx:nginx /var/cache/nginx && \
|
|
29
|
+
chown -R nginx:nginx /var/log/nginx && \
|
|
30
|
+
chown -R nginx:nginx /etc/nginx/conf.d && \
|
|
31
|
+
touch /var/run/nginx.pid && \
|
|
32
|
+
chown -R nginx:nginx /var/run/nginx.pid
|
|
8
33
|
|
|
9
|
-
|
|
10
|
-
RUN sed -i 's/listen *80;/listen {{PORT}};/g' /etc/nginx/conf.d/default.conf
|
|
34
|
+
USER nginx
|
|
11
35
|
|
|
12
36
|
EXPOSE {{PORT}}
|
|
13
37
|
CMD ["nginx", "-g", "daemon off;"]
|