create-stackr 0.2.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/LICENSE +21 -0
- package/README.md +642 -0
- package/bin/cli.js +12 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +113 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/dependencies.d.ts +82 -0
- package/dist/config/dependencies.d.ts.map +1 -0
- package/dist/config/dependencies.js +82 -0
- package/dist/config/dependencies.js.map +1 -0
- package/dist/config/presets.d.ts +3 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +174 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/generators/index.d.ts +40 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +130 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/onboarding.d.ts +8 -0
- package/dist/generators/onboarding.d.ts.map +1 -0
- package/dist/generators/onboarding.js +141 -0
- package/dist/generators/onboarding.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/features.d.ts +14 -0
- package/dist/prompts/features.d.ts.map +1 -0
- package/dist/prompts/features.js +96 -0
- package/dist/prompts/features.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +93 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/onboarding.d.ts +6 -0
- package/dist/prompts/onboarding.d.ts.map +1 -0
- package/dist/prompts/onboarding.js +37 -0
- package/dist/prompts/onboarding.js.map +1 -0
- package/dist/prompts/orm.d.ts +3 -0
- package/dist/prompts/orm.d.ts.map +1 -0
- package/dist/prompts/orm.js +23 -0
- package/dist/prompts/orm.js.map +1 -0
- package/dist/prompts/packageManager.d.ts +2 -0
- package/dist/prompts/packageManager.d.ts.map +1 -0
- package/dist/prompts/packageManager.js +18 -0
- package/dist/prompts/packageManager.js.map +1 -0
- package/dist/prompts/platform.d.ts +3 -0
- package/dist/prompts/platform.d.ts.map +1 -0
- package/dist/prompts/platform.js +21 -0
- package/dist/prompts/platform.js.map +1 -0
- package/dist/prompts/preset.d.ts +4 -0
- package/dist/prompts/preset.d.ts.map +1 -0
- package/dist/prompts/preset.js +165 -0
- package/dist/prompts/preset.js.map +1 -0
- package/dist/prompts/project.d.ts +2 -0
- package/dist/prompts/project.d.ts.map +1 -0
- package/dist/prompts/project.js +27 -0
- package/dist/prompts/project.js.map +1 -0
- package/dist/prompts/sdks.d.ts +2 -0
- package/dist/prompts/sdks.d.ts.map +1 -0
- package/dist/prompts/sdks.js +46 -0
- package/dist/prompts/sdks.js.map +1 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +25 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/cleanup.d.ts +5 -0
- package/dist/utils/cleanup.d.ts.map +1 -0
- package/dist/utils/cleanup.js +38 -0
- package/dist/utils/cleanup.js.map +1 -0
- package/dist/utils/copy.d.ts +10 -0
- package/dist/utils/copy.d.ts.map +1 -0
- package/dist/utils/copy.js +53 -0
- package/dist/utils/copy.js.map +1 -0
- package/dist/utils/errors.d.ts +33 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +136 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/git.d.ts +5 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +33 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/package.d.ts +16 -0
- package/dist/utils/package.d.ts.map +1 -0
- package/dist/utils/package.js +86 -0
- package/dist/utils/package.js.map +1 -0
- package/dist/utils/system-validation.d.ts +9 -0
- package/dist/utils/system-validation.d.ts.map +1 -0
- package/dist/utils/system-validation.js +31 -0
- package/dist/utils/system-validation.js.map +1 -0
- package/dist/utils/template.d.ts +20 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +234 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/validation.d.ts +8 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +94 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +96 -0
- package/templates/base/backend/.dockerignore.ejs +62 -0
- package/templates/base/backend/.env.example.ejs +116 -0
- package/templates/base/backend/Dockerfile.ejs +142 -0
- package/templates/base/backend/controllers/event-queue/index.ts +20 -0
- package/templates/base/backend/controllers/event-queue/workers/user.ts +39 -0
- package/templates/base/backend/controllers/rest-api/index.ts +48 -0
- package/templates/base/backend/controllers/rest-api/plugins/auth.ts +152 -0
- package/templates/base/backend/controllers/rest-api/plugins/config.ts +64 -0
- package/templates/base/backend/controllers/rest-api/plugins/error-handler.ts +118 -0
- package/templates/base/backend/controllers/rest-api/routes/auth.ts.ejs +180 -0
- package/templates/base/backend/controllers/rest-api/routes/device-sessions.ts +197 -0
- package/templates/base/backend/controllers/rest-api/routes/oauth-web.ts.ejs +375 -0
- package/templates/base/backend/controllers/rest-api/server.ts.ejs +87 -0
- package/templates/base/backend/domain/device-session/repository.drizzle.ts +209 -0
- package/templates/base/backend/domain/device-session/repository.prisma.ts +248 -0
- package/templates/base/backend/domain/device-session/schema.ts +72 -0
- package/templates/base/backend/domain/session/repository.drizzle.ts +72 -0
- package/templates/base/backend/domain/session/repository.prisma.ts +72 -0
- package/templates/base/backend/domain/session/schema.ts +29 -0
- package/templates/base/backend/domain/user/repository.drizzle.ts +127 -0
- package/templates/base/backend/domain/user/repository.prisma.ts +115 -0
- package/templates/base/backend/domain/user/schema.ts +14 -0
- package/templates/base/backend/drizzle/schema.drizzle.ts +111 -0
- package/templates/base/backend/drizzle.config.drizzle.ts +13 -0
- package/templates/base/backend/lib/auth.drizzle.ts.ejs +104 -0
- package/templates/base/backend/lib/auth.prisma.ts.ejs +97 -0
- package/templates/base/backend/lib/constants.ts.ejs +29 -0
- package/templates/base/backend/package.json.ejs +50 -0
- package/templates/base/backend/prisma/schema.prisma.ejs +102 -0
- package/templates/base/backend/prisma.config.prisma.ts +12 -0
- package/templates/base/backend/tsconfig.json +39 -0
- package/templates/base/backend/utils/db.drizzle.ts +41 -0
- package/templates/base/backend/utils/db.prisma.ts +51 -0
- package/templates/base/backend/utils/email.ts.ejs +35 -0
- package/templates/base/backend/utils/errors.ts +348 -0
- package/templates/base/backend/utils/redis.ts.ejs +279 -0
- package/templates/base/mobile/.env.example.ejs +35 -0
- package/templates/base/mobile/.gitignore.ejs +167 -0
- package/templates/base/mobile/app/+not-found.tsx +85 -0
- package/templates/base/mobile/app/_layout.tsx.ejs +71 -0
- package/templates/base/mobile/app.json.ejs +88 -0
- package/templates/base/mobile/assets/images/adaptive-icon.png +0 -0
- package/templates/base/mobile/assets/images/favicon.png +0 -0
- package/templates/base/mobile/assets/images/icon.png +0 -0
- package/templates/base/mobile/assets/images/onboarding_page_1.png +0 -0
- package/templates/base/mobile/assets/images/onboarding_page_2.png +0 -0
- package/templates/base/mobile/assets/images/onboarding_page_3.png +0 -0
- package/templates/base/mobile/assets/images/paywall_image.png +0 -0
- package/templates/base/mobile/assets/images/splash.png +0 -0
- package/templates/base/mobile/eas.json.ejs +49 -0
- package/templates/base/mobile/metro.config.js +9 -0
- package/templates/base/mobile/package.json.ejs +53 -0
- package/templates/base/mobile/src/components/ui/Button.tsx +131 -0
- package/templates/base/mobile/src/components/ui/Card.tsx +68 -0
- package/templates/base/mobile/src/components/ui/IconSymbol.tsx +90 -0
- package/templates/base/mobile/src/components/ui/Input.tsx +142 -0
- package/templates/base/mobile/src/components/ui/LoadingSpinner.tsx +98 -0
- package/templates/base/mobile/src/components/ui/OnboardingLayout.tsx +356 -0
- package/templates/base/mobile/src/components/ui/PaywallLayout.tsx +311 -0
- package/templates/base/mobile/src/components/ui/Skeleton.tsx +58 -0
- package/templates/base/mobile/src/components/ui/index.ts +6 -0
- package/templates/base/mobile/src/constants/Theme.ts +163 -0
- package/templates/base/mobile/src/context/ThemeContext.tsx +157 -0
- package/templates/base/mobile/src/lib/auth-client.ts.ejs +51 -0
- package/templates/base/mobile/src/services/api.ts.ejs +71 -0
- package/templates/base/mobile/src/services/errorService.ts +179 -0
- package/templates/base/mobile/src/services/sdkInitializer.ts.ejs +36 -0
- package/templates/base/mobile/src/store/index.ts.ejs +18 -0
- package/templates/base/mobile/src/store/ui.store.ts +100 -0
- package/templates/base/mobile/src/utils/formatters.ts +105 -0
- package/templates/base/mobile/src/utils/logger.ts +73 -0
- package/templates/base/mobile/src/utils/responsive.ts +234 -0
- package/templates/base/mobile/tsconfig.json +32 -0
- package/templates/base/web/.env.example.ejs +26 -0
- package/templates/base/web/components.json +22 -0
- package/templates/base/web/eslint.config.mjs +18 -0
- package/templates/base/web/next.config.ts +7 -0
- package/templates/base/web/package.json.ejs +35 -0
- package/templates/base/web/postcss.config.mjs +7 -0
- package/templates/base/web/public/.gitkeep +0 -0
- package/templates/base/web/public/file.svg +1 -0
- package/templates/base/web/public/globe.svg +1 -0
- package/templates/base/web/public/next.svg +1 -0
- package/templates/base/web/public/vercel.svg +1 -0
- package/templates/base/web/public/window.svg +1 -0
- package/templates/base/web/src/app/favicon.ico +0 -0
- package/templates/base/web/src/app/globals.css +152 -0
- package/templates/base/web/src/app/layout.tsx.ejs +54 -0
- package/templates/base/web/src/app/page.tsx.ejs +92 -0
- package/templates/base/web/src/components/auth/auth-hydrator.tsx.ejs +19 -0
- package/templates/base/web/src/components/auth/protected-route.tsx.ejs +109 -0
- package/templates/base/web/src/components/providers/device-session-setup.tsx.ejs +56 -0
- package/templates/base/web/src/components/providers/theme-provider.tsx +17 -0
- package/templates/base/web/src/components/theme-toggle.tsx +34 -0
- package/templates/base/web/src/components/ui/button.tsx +62 -0
- package/templates/base/web/src/components/ui/card.tsx +92 -0
- package/templates/base/web/src/components/ui/input.tsx +21 -0
- package/templates/base/web/src/components/ui/label.tsx +24 -0
- package/templates/base/web/src/components/ui/skeleton.tsx +13 -0
- package/templates/base/web/src/components/ui/spinner.tsx +20 -0
- package/templates/base/web/src/hooks/use-device-session.ts.ejs +40 -0
- package/templates/base/web/src/hooks/use-session.ts.ejs +56 -0
- package/templates/base/web/src/lib/auth/actions.ts.ejs +334 -0
- package/templates/base/web/src/lib/auth/config.ts.ejs +65 -0
- package/templates/base/web/src/lib/auth/cookies.ts.ejs +74 -0
- package/templates/base/web/src/lib/auth/index.ts.ejs +40 -0
- package/templates/base/web/src/lib/auth/oauth.ts.ejs +72 -0
- package/templates/base/web/src/lib/auth/pkce.ts.ejs +48 -0
- package/templates/base/web/src/lib/auth/sessions.ts.ejs +135 -0
- package/templates/base/web/src/lib/auth/user-agent.ts.ejs +47 -0
- package/templates/base/web/src/lib/device/actions.ts.ejs +148 -0
- package/templates/base/web/src/lib/device/id.ts.ejs +74 -0
- package/templates/base/web/src/lib/utils.ts +6 -0
- package/templates/base/web/src/proxy.ts.ejs +66 -0
- package/templates/base/web/src/store/auth.store.ts.ejs +89 -0
- package/templates/base/web/src/store/deviceSession.store.ts.ejs +141 -0
- package/templates/base/web/tsconfig.json +34 -0
- package/templates/features/mobile/auth/app/(auth)/_layout.tsx +16 -0
- package/templates/features/mobile/auth/app/(auth)/login.tsx +86 -0
- package/templates/features/mobile/auth/app/(auth)/register.tsx +86 -0
- package/templates/features/mobile/auth/components/auth/LoginForm.tsx.ejs +349 -0
- package/templates/features/mobile/auth/components/auth/RegisterForm.tsx.ejs +407 -0
- package/templates/features/mobile/auth/components/auth/index.ts +2 -0
- package/templates/features/mobile/auth/hooks/index.ts.ejs +1 -0
- package/templates/features/mobile/auth/hooks/useAuth.ts.ejs +367 -0
- package/templates/features/mobile/auth/services/deviceSession.ts +370 -0
- package/templates/features/mobile/auth/store/deviceSession.store.ts +326 -0
- package/templates/features/mobile/onboarding/app/(onboarding)/_layout.tsx.ejs +11 -0
- package/templates/features/mobile/onboarding/app/(onboarding)/page-1.tsx.ejs +52 -0
- package/templates/features/mobile/onboarding/app/(onboarding)/page-2.tsx.ejs +52 -0
- package/templates/features/mobile/onboarding/app/(onboarding)/page-3.tsx.ejs +60 -0
- package/templates/features/mobile/paywall/app/paywall.tsx +550 -0
- package/templates/features/mobile/tabs/app/(tabs)/_layout.tsx +26 -0
- package/templates/features/mobile/tabs/app/(tabs)/index.tsx +565 -0
- package/templates/features/web/.gitkeep +0 -0
- package/templates/features/web/auth/app/(app)/dashboard/dashboard-client.tsx.ejs +166 -0
- package/templates/features/web/auth/app/(app)/dashboard/page.tsx.ejs +24 -0
- package/templates/features/web/auth/app/(app)/layout.tsx.ejs +43 -0
- package/templates/features/web/auth/app/(app)/settings/sessions/page.tsx.ejs +29 -0
- package/templates/features/web/auth/app/(app)/settings/sessions/sessions-client.tsx.ejs +77 -0
- package/templates/features/web/auth/app/(auth)/forgot-password/page.tsx.ejs +127 -0
- package/templates/features/web/auth/app/(auth)/layout.tsx.ejs +32 -0
- package/templates/features/web/auth/app/(auth)/login/page.tsx.ejs +35 -0
- package/templates/features/web/auth/app/(auth)/register/page.tsx.ejs +19 -0
- package/templates/features/web/auth/app/(auth)/reset-password/page.tsx.ejs +40 -0
- package/templates/features/web/auth/app/(auth)/verify-email/page.tsx.ejs +198 -0
- package/templates/features/web/auth/app/auth/callback/route.ts.ejs +152 -0
- package/templates/features/web/auth/components/auth/login-form.tsx.ejs +100 -0
- package/templates/features/web/auth/components/auth/oauth-buttons.tsx.ejs +126 -0
- package/templates/features/web/auth/components/auth/password-reset-form.tsx.ejs +103 -0
- package/templates/features/web/auth/components/auth/register-form.tsx.ejs +139 -0
- package/templates/features/web/auth/components/settings/session-card.tsx.ejs +132 -0
- package/templates/integrations/mobile/adjust/services/adjustService.ts.ejs +163 -0
- package/templates/integrations/mobile/adjust/store/adjust.store.ts +243 -0
- package/templates/integrations/mobile/att/services/attService.ts +84 -0
- package/templates/integrations/mobile/att/services/trackingPermissions.ts +208 -0
- package/templates/integrations/mobile/att/store/att.store.ts +162 -0
- package/templates/integrations/mobile/revenuecat/services/revenuecatService.ts.ejs +174 -0
- package/templates/integrations/mobile/revenuecat/store/revenuecat.store.ts +286 -0
- package/templates/integrations/mobile/scate/services/scateService.ts.ejs +85 -0
- package/templates/integrations/mobile/scate/store/scate.store.ts +125 -0
- package/templates/integrations/web/.gitkeep +0 -0
- package/templates/shared/.env.example.ejs +21 -0
- package/templates/shared/.gitignore.ejs +145 -0
- package/templates/shared/README.md.ejs +134 -0
- package/templates/shared/docker-compose.prod.yml.ejs +120 -0
- package/templates/shared/docker-compose.yml.ejs +129 -0
- package/templates/shared/scripts/docker-dev.sh.ejs +395 -0
- package/templates/shared/scripts/docker-prod.sh.ejs +542 -0
- package/templates/shared/scripts/setup.sh.ejs +979 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Production Environment Docker Script
|
|
4
|
+
# Manages the production Docker deployment
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m'
|
|
14
|
+
|
|
15
|
+
print_status() {
|
|
16
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
print_info() {
|
|
20
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
print_warning() {
|
|
24
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
print_error() {
|
|
28
|
+
echo -e "${RED}✗${NC} $1"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Function to show usage
|
|
32
|
+
usage() {
|
|
33
|
+
echo "Full-Stack Auth Boilerplate - Production Environment"
|
|
34
|
+
echo "================================================"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Usage: $0 [COMMAND] [OPTIONS]"
|
|
37
|
+
echo ""
|
|
38
|
+
echo "Commands:"
|
|
39
|
+
echo " deploy Deploy to production"
|
|
40
|
+
echo " stop Stop production environment"
|
|
41
|
+
echo " restart Restart production environment"
|
|
42
|
+
echo " logs Show logs (specify service)"
|
|
43
|
+
echo " status Show status of all services"
|
|
44
|
+
echo " backup Create database backup"
|
|
45
|
+
echo " restore Restore from database backup"
|
|
46
|
+
echo " update Update services (pull latest images)"
|
|
47
|
+
echo " scale Scale services (e.g., backend=3)"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "Options:"
|
|
50
|
+
echo " --with-nginx Include Nginx reverse proxy"
|
|
51
|
+
<% if (backend.eventQueue) { %>
|
|
52
|
+
echo " --with-redis Include Redis service"
|
|
53
|
+
<% } %>
|
|
54
|
+
echo " --build Force rebuild containers"
|
|
55
|
+
echo " --no-backup Skip automatic backup before deploy"
|
|
56
|
+
echo " --only-rest-api Deploy only REST API service"
|
|
57
|
+
<% if (backend.eventQueue) { %>
|
|
58
|
+
echo " --only-event-queue Deploy only Event Queue service"
|
|
59
|
+
<% } %>
|
|
60
|
+
echo ""
|
|
61
|
+
echo "Examples:"
|
|
62
|
+
echo " $0 deploy # Deploy all services"
|
|
63
|
+
echo " $0 deploy --with-nginx # Deploy with Nginx"
|
|
64
|
+
echo " $0 deploy --only-rest-api # Deploy only REST API"
|
|
65
|
+
echo " $0 logs rest-api # Show REST API logs"
|
|
66
|
+
<% if (backend.eventQueue) { %>
|
|
67
|
+
echo " $0 logs event-queue # Show Event Queue logs"
|
|
68
|
+
<% } %>
|
|
69
|
+
echo " $0 backup # Create database backup"
|
|
70
|
+
<% if (backend.eventQueue) { %>
|
|
71
|
+
echo " $0 scale rest-api=2 event-queue=1 # Scale services independently"
|
|
72
|
+
<% } else { %>
|
|
73
|
+
echo " $0 scale rest-api=2 # Scale services"
|
|
74
|
+
<% } %>
|
|
75
|
+
echo ""
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Parse command line arguments
|
|
79
|
+
parse_args() {
|
|
80
|
+
COMMAND=""
|
|
81
|
+
SERVICE=""
|
|
82
|
+
SCALE_ARGS=""
|
|
83
|
+
WITH_NGINX=false
|
|
84
|
+
<% if (backend.eventQueue) { %>
|
|
85
|
+
WITH_REDIS=false
|
|
86
|
+
<% } %>
|
|
87
|
+
FORCE_BUILD=false
|
|
88
|
+
NO_BACKUP=false
|
|
89
|
+
ONLY_REST_API=false
|
|
90
|
+
<% if (backend.eventQueue) { %>
|
|
91
|
+
ONLY_EVENT_QUEUE=false
|
|
92
|
+
<% } %>
|
|
93
|
+
|
|
94
|
+
while [[ $# -gt 0 ]]; do
|
|
95
|
+
case $1 in
|
|
96
|
+
deploy|stop|restart|logs|status|backup|restore|update|scale)
|
|
97
|
+
COMMAND="$1"
|
|
98
|
+
shift
|
|
99
|
+
;;
|
|
100
|
+
rest-api<% if (backend.eventQueue) { %>|event-queue<% } %>|database<% if (backend.eventQueue) { %>|redis<% } %>|nginx)
|
|
101
|
+
SERVICE="$1"
|
|
102
|
+
shift
|
|
103
|
+
;;
|
|
104
|
+
*=*)
|
|
105
|
+
SCALE_ARGS="$1"
|
|
106
|
+
shift
|
|
107
|
+
;;
|
|
108
|
+
--with-nginx)
|
|
109
|
+
WITH_NGINX=true
|
|
110
|
+
shift
|
|
111
|
+
;;
|
|
112
|
+
<% if (backend.eventQueue) { %>
|
|
113
|
+
--with-redis)
|
|
114
|
+
WITH_REDIS=true
|
|
115
|
+
shift
|
|
116
|
+
;;
|
|
117
|
+
<% } %>
|
|
118
|
+
--build)
|
|
119
|
+
FORCE_BUILD=true
|
|
120
|
+
shift
|
|
121
|
+
;;
|
|
122
|
+
--no-backup)
|
|
123
|
+
NO_BACKUP=true
|
|
124
|
+
shift
|
|
125
|
+
;;
|
|
126
|
+
--only-rest-api)
|
|
127
|
+
ONLY_REST_API=true
|
|
128
|
+
shift
|
|
129
|
+
;;
|
|
130
|
+
<% if (backend.eventQueue) { %>
|
|
131
|
+
--only-event-queue)
|
|
132
|
+
ONLY_EVENT_QUEUE=true
|
|
133
|
+
shift
|
|
134
|
+
;;
|
|
135
|
+
<% } %>
|
|
136
|
+
-h|--help)
|
|
137
|
+
usage
|
|
138
|
+
exit 0
|
|
139
|
+
;;
|
|
140
|
+
*)
|
|
141
|
+
echo "Unknown option: $1"
|
|
142
|
+
usage
|
|
143
|
+
exit 1
|
|
144
|
+
;;
|
|
145
|
+
esac
|
|
146
|
+
done
|
|
147
|
+
|
|
148
|
+
if [ -z "$COMMAND" ]; then
|
|
149
|
+
usage
|
|
150
|
+
exit 1
|
|
151
|
+
fi
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Check production requirements
|
|
155
|
+
check_production_requirements() {
|
|
156
|
+
print_info "Checking production requirements..."
|
|
157
|
+
|
|
158
|
+
# Check if .env file exists
|
|
159
|
+
if [ ! -f ".env" ]; then
|
|
160
|
+
print_error "Production .env file is missing!"
|
|
161
|
+
print_info "Create a .env file with production configuration"
|
|
162
|
+
exit 1
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Check critical environment variables
|
|
166
|
+
source .env
|
|
167
|
+
|
|
168
|
+
if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "dev-jwt-secret-change-in-production" ]; then
|
|
169
|
+
print_error "JWT_SECRET is not set or using default value!"
|
|
170
|
+
print_info "Set a strong JWT_SECRET in your .env file"
|
|
171
|
+
exit 1
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
if [ -z "$DB_PASSWORD" ] || [ "$DB_PASSWORD" = "postgres" ]; then
|
|
175
|
+
print_error "DB_PASSWORD is not set or using default value!"
|
|
176
|
+
print_info "Set a strong DB_PASSWORD in your .env file"
|
|
177
|
+
exit 1
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
print_status "Production requirements check passed"
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# Build compose command with profiles
|
|
184
|
+
build_compose_cmd() {
|
|
185
|
+
local cmd="docker-compose -f docker-compose.prod.yml"
|
|
186
|
+
|
|
187
|
+
# Handle microservices profiles
|
|
188
|
+
if [ "$ONLY_REST_API" = true ]; then
|
|
189
|
+
cmd="$cmd --profile rest-api"
|
|
190
|
+
<% if (backend.eventQueue) { %>
|
|
191
|
+
elif [ "$ONLY_EVENT_QUEUE" = true ]; then
|
|
192
|
+
cmd="$cmd --profile event-queue"
|
|
193
|
+
<% } %>
|
|
194
|
+
else
|
|
195
|
+
cmd="$cmd --profile all"
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
if [ "$WITH_NGINX" = true ]; then
|
|
199
|
+
cmd="$cmd --profile with-nginx"
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
<% if (backend.eventQueue) { %>
|
|
203
|
+
if [ "$WITH_REDIS" = true ]; then
|
|
204
|
+
cmd="$cmd --profile with-redis"
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
<% } %>
|
|
208
|
+
echo "$cmd"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# Create backup before deployment
|
|
212
|
+
create_backup() {
|
|
213
|
+
if [ "$NO_BACKUP" = true ]; then
|
|
214
|
+
print_info "Skipping backup (--no-backup flag used)"
|
|
215
|
+
return
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
print_info "Creating pre-deployment backup..."
|
|
219
|
+
|
|
220
|
+
# Create backups directory
|
|
221
|
+
mkdir -p backups
|
|
222
|
+
|
|
223
|
+
# Run backup service
|
|
224
|
+
docker-compose -f docker-compose.prod.yml --profile backup run --rm backup
|
|
225
|
+
|
|
226
|
+
print_status "Backup created successfully"
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
# Deploy to production
|
|
230
|
+
deploy_production() {
|
|
231
|
+
check_production_requirements
|
|
232
|
+
|
|
233
|
+
local compose_cmd=$(build_compose_cmd)
|
|
234
|
+
|
|
235
|
+
print_info "Deploying to production environment..."
|
|
236
|
+
|
|
237
|
+
# Create backup if database is running
|
|
238
|
+
if docker ps | grep -q "auth_boilerplate_db_prod"; then
|
|
239
|
+
create_backup
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
if [ "$FORCE_BUILD" = true ]; then
|
|
243
|
+
print_info "Force rebuilding containers..."
|
|
244
|
+
$compose_cmd build --no-cache
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# Pull latest images
|
|
248
|
+
$compose_cmd pull
|
|
249
|
+
|
|
250
|
+
# Deploy with zero-downtime strategy
|
|
251
|
+
$compose_cmd up -d --remove-orphans
|
|
252
|
+
|
|
253
|
+
# Wait for services to be healthy
|
|
254
|
+
print_info "Waiting for services to be healthy..."
|
|
255
|
+
sleep 30
|
|
256
|
+
|
|
257
|
+
# Check service health
|
|
258
|
+
if health_check_silent; then
|
|
259
|
+
print_status "Production deployment successful!"
|
|
260
|
+
show_production_info
|
|
261
|
+
else
|
|
262
|
+
print_error "Deployment health check failed!"
|
|
263
|
+
print_info "Check logs: $0 logs"
|
|
264
|
+
exit 1
|
|
265
|
+
fi
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
# Stop production services
|
|
269
|
+
stop_production() {
|
|
270
|
+
local compose_cmd=$(build_compose_cmd)
|
|
271
|
+
|
|
272
|
+
print_warning "Stopping production environment..."
|
|
273
|
+
read -p "Are you sure you want to stop production services? (y/N): " -n 1 -r
|
|
274
|
+
echo
|
|
275
|
+
|
|
276
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
277
|
+
$compose_cmd down
|
|
278
|
+
print_status "Production services stopped"
|
|
279
|
+
else
|
|
280
|
+
print_info "Operation cancelled"
|
|
281
|
+
fi
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
# Restart production services
|
|
285
|
+
restart_production() {
|
|
286
|
+
local compose_cmd=$(build_compose_cmd)
|
|
287
|
+
|
|
288
|
+
print_info "Restarting production environment..."
|
|
289
|
+
|
|
290
|
+
if [ "$FORCE_BUILD" = true ]; then
|
|
291
|
+
create_backup
|
|
292
|
+
$compose_cmd down
|
|
293
|
+
$compose_cmd build --no-cache
|
|
294
|
+
$compose_cmd up -d
|
|
295
|
+
else
|
|
296
|
+
$compose_cmd restart
|
|
297
|
+
fi
|
|
298
|
+
|
|
299
|
+
print_status "Production services restarted"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Show logs
|
|
303
|
+
show_logs() {
|
|
304
|
+
local compose_cmd=$(build_compose_cmd)
|
|
305
|
+
|
|
306
|
+
if [ -n "$SERVICE" ]; then
|
|
307
|
+
print_info "Showing logs for $SERVICE..."
|
|
308
|
+
$compose_cmd logs -f --tail=100 "$SERVICE"
|
|
309
|
+
else
|
|
310
|
+
print_info "Showing logs for all services..."
|
|
311
|
+
$compose_cmd logs -f --tail=100
|
|
312
|
+
fi
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
# Show status
|
|
316
|
+
show_status() {
|
|
317
|
+
local compose_cmd=$(build_compose_cmd)
|
|
318
|
+
|
|
319
|
+
print_info "Production Service Status:"
|
|
320
|
+
$compose_cmd ps
|
|
321
|
+
|
|
322
|
+
echo ""
|
|
323
|
+
print_info "Container Health:"
|
|
324
|
+
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep auth_boilerplate_.*_prod || echo "No production containers running"
|
|
325
|
+
|
|
326
|
+
echo ""
|
|
327
|
+
print_info "Resource Usage:"
|
|
328
|
+
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" | grep auth_boilerplate || echo "No containers running"
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
# Create database backup
|
|
332
|
+
create_database_backup() {
|
|
333
|
+
print_info "Creating database backup..."
|
|
334
|
+
|
|
335
|
+
# Ensure backups directory exists
|
|
336
|
+
mkdir -p backups
|
|
337
|
+
|
|
338
|
+
# Run backup service
|
|
339
|
+
docker-compose -f docker-compose.prod.yml --profile backup run --rm backup
|
|
340
|
+
|
|
341
|
+
print_status "Database backup completed"
|
|
342
|
+
|
|
343
|
+
# List recent backups
|
|
344
|
+
print_info "Recent backups:"
|
|
345
|
+
ls -la backups/backup_*.sql.gz 2>/dev/null | tail -5 || echo "No backups found"
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
# Restore from backup
|
|
349
|
+
restore_database() {
|
|
350
|
+
print_warning "This will restore the database from a backup!"
|
|
351
|
+
print_warning "ALL CURRENT DATA WILL BE LOST!"
|
|
352
|
+
|
|
353
|
+
# List available backups
|
|
354
|
+
echo ""
|
|
355
|
+
print_info "Available backups:"
|
|
356
|
+
ls -la backups/backup_*.sql.gz 2>/dev/null || {
|
|
357
|
+
print_error "No backups found!"
|
|
358
|
+
exit 1
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
echo ""
|
|
362
|
+
read -p "Enter backup filename: " backup_file
|
|
363
|
+
|
|
364
|
+
if [ ! -f "backups/$backup_file" ]; then
|
|
365
|
+
print_error "Backup file not found: $backup_file"
|
|
366
|
+
exit 1
|
|
367
|
+
fi
|
|
368
|
+
|
|
369
|
+
read -p "Are you sure you want to restore from $backup_file? (y/N): " -n 1 -r
|
|
370
|
+
echo
|
|
371
|
+
|
|
372
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
373
|
+
print_info "Restoring database from $backup_file..."
|
|
374
|
+
|
|
375
|
+
# Stop services to prevent connections
|
|
376
|
+
<% if (backend.eventQueue) { %>
|
|
377
|
+
docker-compose -f docker-compose.prod.yml stop rest-api event-queue 2>/dev/null || true
|
|
378
|
+
<% } else { %>
|
|
379
|
+
docker-compose -f docker-compose.prod.yml stop rest-api 2>/dev/null || true
|
|
380
|
+
<% } %>
|
|
381
|
+
|
|
382
|
+
# Restore database
|
|
383
|
+
gunzip -c "backups/$backup_file" | docker-compose -f docker-compose.prod.yml exec -T database psql -U postgres -d auth_boilerplate
|
|
384
|
+
|
|
385
|
+
# Start services
|
|
386
|
+
<% if (backend.eventQueue) { %>
|
|
387
|
+
docker-compose -f docker-compose.prod.yml start rest-api event-queue 2>/dev/null || true
|
|
388
|
+
<% } else { %>
|
|
389
|
+
docker-compose -f docker-compose.prod.yml start rest-api 2>/dev/null || true
|
|
390
|
+
<% } %>
|
|
391
|
+
|
|
392
|
+
print_status "Database restore completed"
|
|
393
|
+
else
|
|
394
|
+
print_info "Restore cancelled"
|
|
395
|
+
fi
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# Update services
|
|
399
|
+
update_services() {
|
|
400
|
+
local compose_cmd=$(build_compose_cmd)
|
|
401
|
+
|
|
402
|
+
print_info "Updating production services..."
|
|
403
|
+
|
|
404
|
+
# Create backup first
|
|
405
|
+
create_backup
|
|
406
|
+
|
|
407
|
+
# Pull latest images
|
|
408
|
+
$compose_cmd pull
|
|
409
|
+
|
|
410
|
+
# Restart services with new images
|
|
411
|
+
$compose_cmd up -d --remove-orphans
|
|
412
|
+
|
|
413
|
+
print_status "Services updated successfully"
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
# Scale services
|
|
417
|
+
scale_services() {
|
|
418
|
+
if [ -z "$SCALE_ARGS" ]; then
|
|
419
|
+
print_error "No scale arguments provided!"
|
|
420
|
+
<% if (backend.eventQueue) { %>
|
|
421
|
+
print_info "Example: $0 scale rest-api=2 event-queue=1"
|
|
422
|
+
<% } else { %>
|
|
423
|
+
print_info "Example: $0 scale rest-api=2"
|
|
424
|
+
<% } %>
|
|
425
|
+
exit 1
|
|
426
|
+
fi
|
|
427
|
+
|
|
428
|
+
local compose_cmd=$(build_compose_cmd)
|
|
429
|
+
|
|
430
|
+
print_info "Scaling services: $SCALE_ARGS"
|
|
431
|
+
$compose_cmd up -d --scale $SCALE_ARGS
|
|
432
|
+
|
|
433
|
+
print_status "Services scaled successfully"
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
# Silent health check
|
|
437
|
+
health_check_silent() {
|
|
438
|
+
# Check REST API if it's running
|
|
439
|
+
if docker ps | grep -q "rest_api.*Up" && curl -sf http://localhost:8080/ > /dev/null 2>&1; then
|
|
440
|
+
return 0
|
|
441
|
+
<% if (backend.eventQueue) { %>
|
|
442
|
+
elif [ "$ONLY_EVENT_QUEUE" = true ]; then
|
|
443
|
+
# If only event queue is deployed, check if it's running
|
|
444
|
+
if docker ps | grep -q "event_queue.*Up"; then
|
|
445
|
+
return 0
|
|
446
|
+
fi
|
|
447
|
+
<% } %>
|
|
448
|
+
fi
|
|
449
|
+
|
|
450
|
+
return 1
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
# Show production info
|
|
454
|
+
show_production_info() {
|
|
455
|
+
echo ""
|
|
456
|
+
print_info "Production Services:"
|
|
457
|
+
|
|
458
|
+
if [ "$ONLY_REST_API" = true ]; then
|
|
459
|
+
echo " 🌐 REST API: http://localhost:8080"
|
|
460
|
+
<% if (backend.eventQueue) { %>
|
|
461
|
+
elif [ "$ONLY_EVENT_QUEUE" = true ]; then
|
|
462
|
+
echo " 📋 Event Queue: Running in background (no HTTP interface)"
|
|
463
|
+
<% } %>
|
|
464
|
+
else
|
|
465
|
+
echo " 🌐 REST API: http://localhost:8080"
|
|
466
|
+
<% if (backend.eventQueue) { %>
|
|
467
|
+
echo " 📋 Event Queue: Running in background (no HTTP interface)"
|
|
468
|
+
<% } %>
|
|
469
|
+
fi
|
|
470
|
+
|
|
471
|
+
echo " 🗄️ Database: localhost:5432"
|
|
472
|
+
|
|
473
|
+
if [ "$WITH_NGINX" = true ]; then
|
|
474
|
+
echo " 🔧 Nginx: http://localhost"
|
|
475
|
+
fi
|
|
476
|
+
|
|
477
|
+
<% if (backend.eventQueue) { %>
|
|
478
|
+
if [ "$WITH_REDIS" = true ]; then
|
|
479
|
+
echo " 🔄 Redis: localhost:6379"
|
|
480
|
+
fi
|
|
481
|
+
|
|
482
|
+
<% } %>
|
|
483
|
+
echo ""
|
|
484
|
+
print_info "Monitoring commands:"
|
|
485
|
+
echo " $0 logs # View all logs"
|
|
486
|
+
echo " $0 logs rest-api # View REST API logs"
|
|
487
|
+
<% if (backend.eventQueue) { %>
|
|
488
|
+
echo " $0 logs event-queue # View Event Queue logs"
|
|
489
|
+
<% } %>
|
|
490
|
+
echo " $0 status # Check service status"
|
|
491
|
+
echo " $0 backup # Create backup"
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
# Main execution
|
|
495
|
+
main() {
|
|
496
|
+
# Check if we're in the right directory
|
|
497
|
+
if [ ! -f "docker-compose.prod.yml" ]; then
|
|
498
|
+
print_error "docker-compose.prod.yml not found!"
|
|
499
|
+
print_info "Please run this script from the project root directory"
|
|
500
|
+
exit 1
|
|
501
|
+
fi
|
|
502
|
+
|
|
503
|
+
parse_args "$@"
|
|
504
|
+
|
|
505
|
+
case $COMMAND in
|
|
506
|
+
deploy)
|
|
507
|
+
deploy_production
|
|
508
|
+
;;
|
|
509
|
+
stop)
|
|
510
|
+
stop_production
|
|
511
|
+
;;
|
|
512
|
+
restart)
|
|
513
|
+
restart_production
|
|
514
|
+
;;
|
|
515
|
+
logs)
|
|
516
|
+
show_logs
|
|
517
|
+
;;
|
|
518
|
+
status)
|
|
519
|
+
show_status
|
|
520
|
+
;;
|
|
521
|
+
backup)
|
|
522
|
+
create_database_backup
|
|
523
|
+
;;
|
|
524
|
+
restore)
|
|
525
|
+
restore_database
|
|
526
|
+
;;
|
|
527
|
+
update)
|
|
528
|
+
update_services
|
|
529
|
+
;;
|
|
530
|
+
scale)
|
|
531
|
+
scale_services
|
|
532
|
+
;;
|
|
533
|
+
*)
|
|
534
|
+
print_error "Unknown command: $COMMAND"
|
|
535
|
+
usage
|
|
536
|
+
exit 1
|
|
537
|
+
;;
|
|
538
|
+
esac
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
# Run main function
|
|
542
|
+
main "$@"
|