kybernus 2.4.0 → 3.0.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.
Files changed (137) hide show
  1. package/README.md +15 -6
  2. package/add-features/auth/java-spring/AuthController.java +54 -0
  3. package/add-features/auth/java-spring/AuthService.java +85 -0
  4. package/add-features/auth/java-spring/INSTRUCTIONS.md +119 -0
  5. package/add-features/auth/java-spring/dto/LoginRequest.java +22 -0
  6. package/add-features/auth/java-spring/dto/RegisterRequest.java +22 -0
  7. package/add-features/auth/java-spring/security/JwtRequestFilter.java +45 -0
  8. package/add-features/auth/java-spring/security/JwtUtil.java +59 -0
  9. package/add-features/auth/java-spring/security/SecurityConfig.java +39 -0
  10. package/add-features/auth/nestjs/INSTRUCTIONS.md +112 -0
  11. package/add-features/auth/nestjs/auth.controller.ts +27 -0
  12. package/add-features/auth/nestjs/auth.module.ts +20 -0
  13. package/add-features/auth/nestjs/auth.service.ts +81 -0
  14. package/add-features/auth/nestjs/dto/login.dto.ts +4 -0
  15. package/add-features/auth/nestjs/dto/register.dto.ts +4 -0
  16. package/add-features/auth/nestjs/jwt-auth.guard.ts +17 -0
  17. package/add-features/auth/nestjs/jwt.strategy.ts +24 -0
  18. package/add-features/auth/nextjs/INSTRUCTIONS.md +97 -0
  19. package/add-features/auth/nextjs/jwt.ts +21 -0
  20. package/add-features/auth/nextjs/middleware.ts +37 -0
  21. package/add-features/auth/nextjs/routes/login.ts +43 -0
  22. package/add-features/auth/nextjs/routes/register.ts +50 -0
  23. package/add-features/auth/nextjs/session.ts +28 -0
  24. package/add-features/auth/nodejs-express/INSTRUCTIONS.md +109 -0
  25. package/add-features/auth/nodejs-express/auth.controller.ts +59 -0
  26. package/add-features/auth/nodejs-express/auth.middleware.ts +38 -0
  27. package/add-features/auth/nodejs-express/auth.routes.ts +15 -0
  28. package/add-features/auth/nodejs-express/auth.service.ts +73 -0
  29. package/add-features/auth/nodejs-express/jwt.config.ts +17 -0
  30. package/add-features/auth/python-fastapi/INSTRUCTIONS.md +100 -0
  31. package/add-features/auth/python-fastapi/router.py +26 -0
  32. package/add-features/auth/python-fastapi/schemas.py +25 -0
  33. package/add-features/auth/python-fastapi/security.py +37 -0
  34. package/add-features/auth/python-fastapi/service.py +61 -0
  35. package/add-features/deploy/dockerfiles/Dockerfile.java +22 -0
  36. package/add-features/deploy/dockerfiles/Dockerfile.nextjs +32 -0
  37. package/add-features/deploy/dockerfiles/Dockerfile.nodejs +25 -0
  38. package/add-features/deploy/dockerfiles/Dockerfile.python +17 -0
  39. package/add-features/deploy/fly/INSTRUCTIONS.md +39 -0
  40. package/add-features/deploy/fly/java-spring.toml +21 -0
  41. package/add-features/deploy/fly/nextjs.toml +16 -0
  42. package/add-features/deploy/fly/nodejs.toml +21 -0
  43. package/add-features/deploy/fly/python-fastapi.toml +21 -0
  44. package/add-features/deploy/railway/INSTRUCTIONS.md +38 -0
  45. package/add-features/deploy/railway/java-spring.toml +16 -0
  46. package/add-features/deploy/railway/nextjs.toml +14 -0
  47. package/add-features/deploy/railway/nodejs.toml +14 -0
  48. package/add-features/deploy/railway/python-fastapi.toml +13 -0
  49. package/add-features/deploy/render/INSTRUCTIONS.md +35 -0
  50. package/add-features/deploy/render/java-spring.yaml +14 -0
  51. package/add-features/deploy/render/nextjs.yaml +17 -0
  52. package/add-features/deploy/render/nodejs.yaml +15 -0
  53. package/add-features/deploy/render/python-fastapi.yaml +13 -0
  54. package/add-features/deploy/vercel/INSTRUCTIONS.md +40 -0
  55. package/add-features/deploy/vercel/nextjs.json +16 -0
  56. package/add-features/deploy/vercel/nodejs-express.json +21 -0
  57. package/add-features/deploy/vercel/python-fastapi.json +21 -0
  58. package/add-features/husky/INSTRUCTIONS.md +52 -0
  59. package/add-features/husky/commit-msg +4 -0
  60. package/add-features/husky/commitlint.config.js +3 -0
  61. package/add-features/husky/pre-commit +4 -0
  62. package/add-features/redis/.env.snippet +1 -0
  63. package/add-features/redis/INSTRUCTIONS.md +64 -0
  64. package/add-features/redis/docker-compose.snippet.yml +18 -0
  65. package/add-features/redis/java-spring.java +27 -0
  66. package/add-features/redis/nextjs.ts +23 -0
  67. package/add-features/redis/nodejs.ts +14 -0
  68. package/add-features/redis/python.py +22 -0
  69. package/add-features/swagger/INSTRUCTIONS.md +53 -0
  70. package/add-features/swagger/java-spring.java +34 -0
  71. package/add-features/swagger/nestjs.ts +16 -0
  72. package/add-features/swagger/nextjs-route.ts +11 -0
  73. package/add-features/swagger/nextjs-swagger.ts +17 -0
  74. package/add-features/swagger/nodejs-express.ts +30 -0
  75. package/add-features/swagger/python-fastapi.py +21 -0
  76. package/add-features/websocket/INSTRUCTIONS.md +63 -0
  77. package/add-features/websocket/java-spring.java +60 -0
  78. package/add-features/websocket/nestjs.ts +38 -0
  79. package/add-features/websocket/nodejs-express.ts +38 -0
  80. package/add-features/websocket/python-fastapi.py +41 -0
  81. package/dist/cli/commands/add.d.ts +11 -0
  82. package/dist/cli/commands/add.d.ts.map +1 -0
  83. package/dist/cli/commands/add.js +102 -0
  84. package/dist/cli/commands/add.js.map +1 -0
  85. package/dist/cli/commands/auth.d.ts +11 -0
  86. package/dist/cli/commands/auth.d.ts.map +1 -0
  87. package/dist/cli/commands/auth.js +71 -0
  88. package/dist/cli/commands/auth.js.map +1 -0
  89. package/dist/cli/commands/deploy.d.ts +10 -0
  90. package/dist/cli/commands/deploy.d.ts.map +1 -0
  91. package/dist/cli/commands/deploy.js +110 -0
  92. package/dist/cli/commands/deploy.js.map +1 -0
  93. package/dist/cli/commands/doctor.d.ts +3 -0
  94. package/dist/cli/commands/doctor.d.ts.map +1 -0
  95. package/dist/cli/commands/doctor.js +110 -0
  96. package/dist/cli/commands/doctor.js.map +1 -0
  97. package/dist/cli/commands/init.d.ts +1 -0
  98. package/dist/cli/commands/init.d.ts.map +1 -1
  99. package/dist/cli/commands/init.js +1 -0
  100. package/dist/cli/commands/init.js.map +1 -1
  101. package/dist/cli/prompts/wizard.d.ts +1 -0
  102. package/dist/cli/prompts/wizard.d.ts.map +1 -1
  103. package/dist/cli/prompts/wizard.js +23 -15
  104. package/dist/cli/prompts/wizard.js.map +1 -1
  105. package/dist/cli/utils/cli-helpers.d.ts +43 -0
  106. package/dist/cli/utils/cli-helpers.d.ts.map +1 -0
  107. package/dist/cli/utils/cli-helpers.js +107 -0
  108. package/dist/cli/utils/cli-helpers.js.map +1 -0
  109. package/dist/core/deploy/deploy-generator.d.ts +18 -0
  110. package/dist/core/deploy/deploy-generator.d.ts.map +1 -0
  111. package/dist/core/deploy/deploy-generator.js +155 -0
  112. package/dist/core/deploy/deploy-generator.js.map +1 -0
  113. package/dist/core/features/feature-generator.d.ts +26 -0
  114. package/dist/core/features/feature-generator.d.ts.map +1 -0
  115. package/dist/core/features/feature-generator.js +376 -0
  116. package/dist/core/features/feature-generator.js.map +1 -0
  117. package/dist/core/generator/project.d.ts.map +1 -1
  118. package/dist/core/generator/project.js +42 -2
  119. package/dist/core/generator/project.js.map +1 -1
  120. package/dist/core/templates/engine.d.ts.map +1 -1
  121. package/dist/core/templates/engine.js +4 -0
  122. package/dist/core/templates/engine.js.map +1 -1
  123. package/dist/index.js +9 -0
  124. package/dist/index.js.map +1 -1
  125. package/dist/models/config.d.ts +1 -0
  126. package/dist/models/config.d.ts.map +1 -1
  127. package/package.json +14 -2
  128. package/templates/nestjs/clean/package.json.hbs +51 -41
  129. package/templates/nestjs/hexagonal/package.json.hbs +51 -41
  130. package/templates/nestjs/mvc/package.json.hbs +49 -39
  131. package/templates/nextjs/mvc/package.json.hbs +46 -36
  132. package/templates/nodejs-express/clean/package.json.hbs +69 -59
  133. package/templates/nodejs-express/hexagonal/package.json.hbs +69 -59
  134. package/templates/nodejs-express/mvc/package.json.hbs +67 -57
  135. /package/templates/nestjs/hexagonal/prisma/{schema.prisma → schema.prisma.hbs} +0 -0
  136. /package/templates/nodejs-express/clean/prisma/{schema.prisma → schema.prisma.hbs} +0 -0
  137. /package/templates/nodejs-express/hexagonal/prisma/{schema.prisma → schema.prisma.hbs} +0 -0
@@ -0,0 +1,73 @@
1
+ import { generateToken } from './jwt.config';
2
+ import bcrypt from 'bcryptjs';
3
+
4
+ // ==========================================
5
+ // 🚨 TODO: DATABASE INTEGRATION REQUIRED 🚨
6
+ // ==========================================
7
+ // This service currently uses an IN-MEMORY array to store users.
8
+ // You MUST replace the "mockDb" logic below with your actual ORM or Database provider.
9
+ //
10
+ // EXAMPLE WITH PRISMA:
11
+ // 1. import { PrismaClient } from '@prisma/client';
12
+ // const prisma = new PrismaClient();
13
+ // 2. To find user: const user = await prisma.user.findUnique({ where: { email } });
14
+ // 3. To create user: const user = await prisma.user.create({ data: { email, password: hashedPassword } });
15
+ // ==========================================
16
+
17
+ const mockDb: any[] = []; // 🚨 REPLACE THIS WITH REAL DB CALLS 🚨
18
+
19
+ export class AuthService {
20
+
21
+ async register(email: string, password: string) {
22
+ // 🚨 TODO: Change this to checking your real database!
23
+ const existingUser = mockDb.find((u) => u.email === email);
24
+ if (existingUser) {
25
+ throw new Error('User already exists');
26
+ }
27
+
28
+ const hashedPassword = await bcrypt.hash(password, 12);
29
+
30
+ // 🚨 TODO: Change this to inserting into your real database!
31
+ const newUser = {
32
+ id: Math.random().toString(36).substring(7), // Mock ID
33
+ email,
34
+ password: hashedPassword,
35
+ };
36
+ mockDb.push(newUser);
37
+
38
+ const token = generateToken({ userId: newUser.id, email: newUser.email });
39
+
40
+ // Do not return password hash
41
+ const { password: _, ...userWithoutPassword } = newUser;
42
+ return { user: userWithoutPassword, token };
43
+ }
44
+
45
+ async login(email: string, password: string) {
46
+ // 🚨 TODO: Change this to fetching from your real database!
47
+ const user = mockDb.find((u) => u.email === email);
48
+
49
+ if (!user) {
50
+ throw new Error('Invalid credentials');
51
+ }
52
+
53
+ const isMatch = await bcrypt.compare(password, user.password);
54
+ if (!isMatch) {
55
+ throw new Error('Invalid credentials');
56
+ }
57
+
58
+ const token = generateToken({ userId: user.id, email: user.email });
59
+
60
+ return { token };
61
+ }
62
+
63
+ async getUserProfile(userId: string) {
64
+ // 🚨 TODO: Change this to fetching from your real database!
65
+ const user = mockDb.find((u) => u.id === userId);
66
+ if (!user) {
67
+ throw new Error('User not found');
68
+ }
69
+
70
+ const { password, ...profile } = user;
71
+ return profile;
72
+ }
73
+ }
@@ -0,0 +1,17 @@
1
+ import jwt from 'jsonwebtoken';
2
+
3
+ const JWT_SECRET = process.env.JWT_SECRET || 'change-me-in-production';
4
+ const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '7d';
5
+
6
+ export interface JwtPayload {
7
+ userId: string;
8
+ email: string;
9
+ }
10
+
11
+ export function generateToken(payload: JwtPayload): string {
12
+ return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
13
+ }
14
+
15
+ export function verifyToken(token: string): JwtPayload {
16
+ return jwt.verify(token, JWT_SECRET) as JwtPayload;
17
+ }
@@ -0,0 +1,100 @@
1
+ # 🔐 JWT Authentication Module — Python FastAPI
2
+
3
+ A complete, modular authentication flow was added to your project inside the `app/auth/` directory.
4
+
5
+ ## 📁 Files generated:
6
+
7
+ - `router.py` — The FastAPI `APIRouter` exposing `/auth/login`, `/auth/register`, and `/auth/me`.
8
+ - `service.py` — Business logic (password validation, checking user). **🚨 ACTION REQUIRED HERE**
9
+ - `security.py` — JWT token generation and password hashing (passlib).
10
+ - `schemas.py` — Pydantic models for request/response validation.
11
+
12
+ ## 📦 1. Install Dependencies
13
+
14
+ You need to install the cryptography and hashing libraries:
15
+
16
+ ```bash
17
+ pip install python-jose[cryptography] passlib[bcrypt] python-multipart
18
+ ```
19
+
20
+ ## ⚙️ 2. Environment Variables
21
+
22
+ Add these to your `.env` file at the root of your project:
23
+
24
+ ```
25
+ JWT_SECRET=your-super-secret-key-change-me
26
+ JWT_EXPIRES_MINUTES=10080
27
+ ```
28
+
29
+ > 💡 **Tip:** Generate a strong random secret by running this:
30
+ > `python -c "import secrets; print(secrets.token_hex(64))"`
31
+
32
+ ---
33
+
34
+ ## 🚨 3. MANDATORY ACTION: Connect to your Database
35
+
36
+ The generated `service.py` uses an **IN-MEMORY MOCK DATABASE** by default so that the API compiles and runs immediately.
37
+ You **MUST** replace this with calls to your actual Database (SQLAlchemy, SQLModel, Motor, etc).
38
+
39
+ **Open `app/auth/service.py` and look for the `🚨 TODO` blocks.**
40
+
41
+ ### Example: How to connect it to SQLAlchemy:
42
+
43
+ ```python
44
+ # Inside app/auth/service.py
45
+
46
+ from sqlalchemy.orm import Session
47
+ from app.db.models import User
48
+
49
+ # Add 'db: Session' parameter so router can inject it
50
+ def auth_register(user_data: UserCreate, db: Session) -> dict:
51
+ existing = db.query(User).filter(User.email == user_data.email).first()
52
+ if existing:
53
+ raise HTTPException(status_code=409, detail="User already exists")
54
+
55
+ hashed_password = hash_password(user_data.password)
56
+
57
+ new_user = User(email=user_data.email, password=hashed_password)
58
+ db.add(new_user)
59
+ db.commit()
60
+ db.refresh(new_user)
61
+
62
+ token = create_access_token(data={"sub": str(new_user.id), "email": new_user.email})
63
+ return {"user": new_user, "access_token": token, "token_type": "bearer"}
64
+ ```
65
+ *(Remember to update `router.py` endpoints to pass the `db: Session = Depends(get_db)` to the service).*
66
+
67
+ ---
68
+
69
+ ## ⚡ 4. Plug the Router into your App
70
+
71
+ Currently, the `router.py` exists, but your FastAPI app doesn't know about it.
72
+ You must include it in your main application instance.
73
+
74
+ **Open `app/main.py` and add:**
75
+
76
+ ```python
77
+ from fastapi import FastAPI
78
+ from app.auth.router import router as auth_router # <-- Import this
79
+
80
+ app = FastAPI()
81
+
82
+ app.include_router(auth_router) # <-- Register it
83
+ ```
84
+
85
+ ## 🔒 5. How to protect other routes
86
+
87
+ You can secure any other route by using the `get_current_user` dependency:
88
+
89
+ ```python
90
+ from fastapi import APIRouter, Depends
91
+ from app.auth.router import get_current_user
92
+
93
+ router = APIRouter(prefix="/admin")
94
+
95
+ # The Depend() ensures a valid JWT is present before hitting this code
96
+ @router.get("/dashboard")
97
+ async def dashboard(user: dict = Depends(get_current_user)):
98
+ # You now have access to the logged-in user's payload!
99
+ return {"message": f"Welcome back, {user['email']}"}
100
+ ```
@@ -0,0 +1,26 @@
1
+ from fastapi import APIRouter, Depends, HTTPException
2
+ from .schemas import UserCreate, UserLogin, TokenResponse, RegisterResponse, UserResponse
3
+ from .service import auth_register, auth_login, get_user_profile
4
+ from .security import oauth2_scheme, decode_token
5
+
6
+ router = APIRouter(prefix="/auth", tags=["Authentication"])
7
+
8
+ def get_current_user(token: str = Depends(oauth2_scheme)) -> dict:
9
+ """Dependency for securing endpoints."""
10
+ payload = decode_token(token)
11
+ user_id = payload.get("sub")
12
+ if not user_id:
13
+ raise HTTPException(status_code=401, detail="Invalid token structure")
14
+ return {"user_id": user_id, "email": payload.get("email")}
15
+
16
+ @router.post("/register", response_model=RegisterResponse, status_code=201)
17
+ def register(user_data: UserCreate):
18
+ return auth_register(user_data)
19
+
20
+ @router.post("/login", response_model=TokenResponse)
21
+ def login(user_data: UserLogin):
22
+ return auth_login(user_data)
23
+
24
+ @router.get("/me", response_model=UserResponse)
25
+ def get_me(current_user: dict = Depends(get_current_user)):
26
+ return get_user_profile(current_user["user_id"])
@@ -0,0 +1,25 @@
1
+ from pydantic import BaseModel, EmailStr
2
+
3
+ class UserBase(BaseModel):
4
+ email: EmailStr
5
+
6
+ class UserCreate(UserBase):
7
+ password: str
8
+
9
+ class UserLogin(UserBase):
10
+ password: str
11
+
12
+ class UserResponse(UserBase):
13
+ id: str
14
+
15
+ class Config:
16
+ from_attributes = True
17
+
18
+ class TokenResponse(BaseModel):
19
+ access_token: str
20
+ token_type: str = "bearer"
21
+
22
+ class RegisterResponse(BaseModel):
23
+ user: UserResponse
24
+ access_token: str
25
+ token_type: str = "bearer"
@@ -0,0 +1,37 @@
1
+ import os
2
+ from datetime import datetime, timedelta, timezone
3
+ from typing import Optional
4
+
5
+ from fastapi import Depends, HTTPException, status
6
+ from fastapi.security import OAuth2PasswordBearer
7
+ from jose import JWTError, jwt
8
+ from passlib.context import CryptContext
9
+
10
+ JWT_SECRET = os.getenv("JWT_SECRET", "change-me-in-production")
11
+ JWT_ALGORITHM = "HS256"
12
+ JWT_EXPIRES_MINUTES = int(os.getenv("JWT_EXPIRES_MINUTES", "10080")) # 7 days
13
+
14
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
15
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/login")
16
+
17
+ def hash_password(password: str) -> str:
18
+ return pwd_context.hash(password)
19
+
20
+ def verify_password(plain: str, hashed: str) -> bool:
21
+ return pwd_context.verify(plain, hashed)
22
+
23
+ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
24
+ to_encode = data.copy()
25
+ expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=JWT_EXPIRES_MINUTES))
26
+ to_encode.update({"exp": expire})
27
+ return jwt.encode(to_encode, JWT_SECRET, algorithm=JWT_ALGORITHM)
28
+
29
+ def decode_token(token: str) -> dict:
30
+ try:
31
+ return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
32
+ except JWTError:
33
+ raise HTTPException(
34
+ status_code=status.HTTP_401_UNAUTHORIZED,
35
+ detail="Invalid or expired token",
36
+ headers={"WWW-Authenticate": "Bearer"},
37
+ )
@@ -0,0 +1,61 @@
1
+ from fastapi import HTTPException
2
+ from .security import hash_password, verify_password, create_access_token
3
+ from .schemas import UserCreate, UserLogin
4
+
5
+ # ==========================================
6
+ # 🚨 TODO: DATABASE INTEGRATION REQUIRED 🚨
7
+ # ==========================================
8
+ # This service currently uses an IN-MEMORY list to store users.
9
+ # You MUST replace the "mock_db" logic below with your SQLAlchemy sessions
10
+ # or other ORM tool.
11
+ #
12
+ # EXAMPLE WITH SQLALCHEMY:
13
+ # def register_user(db: Session, user_data: UserCreate):
14
+ # existing = db.query(User).filter(User.email == user_data.email).first()
15
+ # if existing: ...
16
+ # ==========================================
17
+
18
+ mock_db = [] # 🚨 REPLACE THIS WITH REAL DB CALLS 🚨
19
+
20
+ def auth_register(user_data: UserCreate) -> dict:
21
+ # 🚨 TODO: Check real DB
22
+ existing_user = next((u for u in mock_db if u["email"] == user_data.email), None)
23
+ if existing_user:
24
+ raise HTTPException(status_code=409, detail="User already exists")
25
+
26
+ hashed_password = hash_password(user_data.password)
27
+
28
+ # 🚨 TODO: Insert into real DB
29
+ import uuid
30
+ new_user = {
31
+ "id": str(uuid.uuid4()),
32
+ "email": user_data.email,
33
+ "password": hashed_password
34
+ }
35
+ mock_db.append(new_user)
36
+
37
+ token = create_access_token(data={"sub": new_user["id"], "email": new_user["email"]})
38
+
39
+ return {
40
+ "user": {"id": new_user["id"], "email": new_user["email"]},
41
+ "access_token": token,
42
+ "token_type": "bearer"
43
+ }
44
+
45
+ def auth_login(user_data: UserLogin) -> dict:
46
+ # 🚨 TODO: Fetch from real DB
47
+ user = next((u for u in mock_db if u["email"] == user_data.email), None)
48
+
49
+ if not user or not verify_password(user_data.password, user["password"]):
50
+ raise HTTPException(status_code=401, detail="Invalid credentials")
51
+
52
+ token = create_access_token(data={"sub": user["id"], "email": user["email"]})
53
+ return {"access_token": token, "token_type": "bearer"}
54
+
55
+ def get_user_profile(user_id: str) -> dict:
56
+ # 🚨 TODO: Fetch from real DB
57
+ user = next((u for u in mock_db if u["id"] == user_id), None)
58
+ if not user:
59
+ raise HTTPException(status_code=404, detail="User not found")
60
+
61
+ return {"id": user["id"], "email": user["email"]}
@@ -0,0 +1,22 @@
1
+ # ── Build stage ───────────────────────────────────────────────────
2
+ FROM maven:3.9-eclipse-temurin-21 AS builder
3
+
4
+ WORKDIR /app
5
+
6
+ COPY pom.xml .
7
+ # Pre-download dependencies for caching
8
+ RUN mvn dependency:go-offline -B
9
+
10
+ COPY src ./src
11
+ RUN mvn package -DskipTests -B
12
+
13
+ # ── Runtime stage ─────────────────────────────────────────────────
14
+ FROM eclipse-temurin:21-jre-alpine
15
+
16
+ WORKDIR /app
17
+
18
+ COPY --from=builder /app/target/*.jar app.jar
19
+
20
+ EXPOSE 8080
21
+
22
+ ENTRYPOINT ["java", "-jar", "app.jar"]
@@ -0,0 +1,32 @@
1
+ FROM node:20-alpine AS deps
2
+ WORKDIR /app
3
+ COPY package*.json ./
4
+ RUN npm ci
5
+
6
+ FROM node:20-alpine AS builder
7
+ WORKDIR /app
8
+ COPY --from=deps /app/node_modules ./node_modules
9
+ COPY . .
10
+ RUN npm run build
11
+
12
+ # ── Production runner ─────────────────────────────────────────────
13
+ FROM node:20-alpine AS runner
14
+ WORKDIR /app
15
+
16
+ ENV NODE_ENV=production
17
+
18
+ RUN addgroup --system --gid 1001 nodejs
19
+ RUN adduser --system --uid 1001 nextjs
20
+
21
+ COPY --from=builder /app/public ./public
22
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
23
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
24
+
25
+ USER nextjs
26
+
27
+ EXPOSE 3000
28
+
29
+ ENV PORT=3000
30
+ ENV HOSTNAME="0.0.0.0"
31
+
32
+ CMD ["node", "server.js"]
@@ -0,0 +1,25 @@
1
+ FROM node:20-alpine AS builder
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+ RUN npm ci
7
+
8
+ COPY . .
9
+ RUN npm run build
10
+
11
+ # ── Production image ──────────────────────────────────────────────
12
+ FROM node:20-alpine AS runner
13
+
14
+ WORKDIR /app
15
+
16
+ ENV NODE_ENV=production
17
+
18
+ COPY --from=builder /app/package*.json ./
19
+ RUN npm ci --only=production
20
+
21
+ COPY --from=builder /app/dist ./dist
22
+
23
+ EXPOSE 3000
24
+
25
+ CMD ["node", "dist/index.js"]
@@ -0,0 +1,17 @@
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y --no-install-recommends \
7
+ gcc \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ COPY requirements.txt .
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ COPY . .
14
+
15
+ EXPOSE 8000
16
+
17
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,39 @@
1
+ # 🚀 Deploy to Fly.io
2
+
3
+ Your deployment configuration has been generated for **Fly.io**.
4
+
5
+ ## 📁 Files generated
6
+
7
+ - `fly.toml` — Fly.io app configuration
8
+ - `Dockerfile` — Container image definition
9
+
10
+ ## 🔧 1. Install the Fly CLI
11
+
12
+ ```bash
13
+ # macOS
14
+ brew install flyctl
15
+
16
+ # Linux / WSL
17
+ curl -L https://fly.io/install.sh | sh
18
+ ```
19
+
20
+ ## 🔑 2. Set Secrets (Environment Variables)
21
+
22
+ ```bash
23
+ fly secrets set DATABASE_URL="your-db-connection-string"
24
+ fly secrets set JWT_SECRET="$(node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")"
25
+ ```
26
+
27
+ ## ⚡ 3. Deploy
28
+
29
+ ```bash
30
+ fly auth login
31
+ fly launch # First time: creates the app and allocates resources
32
+ fly deploy # Subsequent deploys
33
+ ```
34
+
35
+ > 💡 **Tip:** `fly launch` will walk you through a wizard. When it asks "Would you like to deploy now?", you can say Yes.
36
+
37
+ ## 📖 More Info
38
+ - [Fly.io Docs](https://fly.io/docs)
39
+ - [fly.toml Reference](https://fly.io/docs/reference/configuration)
@@ -0,0 +1,21 @@
1
+ app = "my-spring-app"
2
+ primary_region = "gru"
3
+
4
+ [build]
5
+ dockerfile = "Dockerfile"
6
+
7
+ [http_service]
8
+ internal_port = 8080
9
+ force_https = true
10
+ auto_stop_machines = true
11
+ auto_start_machines = true
12
+
13
+ [http_service.concurrency]
14
+ type = "connections"
15
+ hard_limit = 25
16
+ soft_limit = 20
17
+
18
+ [[vm]]
19
+ memory = "512mb"
20
+ cpu_kind = "shared"
21
+ cpus = 1
@@ -0,0 +1,16 @@
1
+ app = "my-nextjs-app"
2
+ primary_region = "gru"
3
+
4
+ [build]
5
+ dockerfile = "Dockerfile"
6
+
7
+ [http_service]
8
+ internal_port = 3000
9
+ force_https = true
10
+ auto_stop_machines = true
11
+ auto_start_machines = true
12
+
13
+ [[vm]]
14
+ memory = "512mb"
15
+ cpu_kind = "shared"
16
+ cpus = 1
@@ -0,0 +1,21 @@
1
+ app = "my-node-app"
2
+ primary_region = "gru"
3
+
4
+ [build]
5
+ dockerfile = "Dockerfile"
6
+
7
+ [http_service]
8
+ internal_port = 3000
9
+ force_https = true
10
+ auto_stop_machines = true
11
+ auto_start_machines = true
12
+
13
+ [http_service.concurrency]
14
+ type = "connections"
15
+ hard_limit = 25
16
+ soft_limit = 20
17
+
18
+ [[vm]]
19
+ memory = "256mb"
20
+ cpu_kind = "shared"
21
+ cpus = 1
@@ -0,0 +1,21 @@
1
+ app = "my-fastapi-app"
2
+ primary_region = "gru"
3
+
4
+ [build]
5
+ dockerfile = "Dockerfile"
6
+
7
+ [http_service]
8
+ internal_port = 8000
9
+ force_https = true
10
+ auto_stop_machines = true
11
+ auto_start_machines = true
12
+
13
+ [http_service.concurrency]
14
+ type = "connections"
15
+ hard_limit = 25
16
+ soft_limit = 20
17
+
18
+ [[vm]]
19
+ memory = "256mb"
20
+ cpu_kind = "shared"
21
+ cpus = 1
@@ -0,0 +1,38 @@
1
+ # 🚀 Deploy to Railway
2
+
3
+ Your deployment configuration has been generated for **Railway**.
4
+
5
+ ## 📁 Files generated
6
+
7
+ - `railway.toml` — Railway project configuration
8
+
9
+ ## 🔑 1. Set Environment Variables
10
+
11
+ 1. Go to [railway.app](https://railway.app) → Your Project → **Variables**
12
+ 2. Add each variable from your `.env` file:
13
+
14
+ | Variable | Description |
15
+ |---|---|
16
+ | `DATABASE_URL` | Your database connection string |
17
+ | `JWT_SECRET` | A strong, random secret for JWT signing |
18
+ | `NODE_ENV` / `PYTHON_ENV` | Set to `production` |
19
+
20
+ > 💡 Railway can also **provision a Postgres database** for you directly — click **New → Database → Postgres** in your project.
21
+
22
+ ## ⚡ 2. Deploy
23
+
24
+ **Option A — GitHub Auto-Deploy (recommended):**
25
+ 1. Go to [railway.app](https://railway.app) → **New Project** → **Deploy from GitHub repo**
26
+ 2. Select your repo — Railway auto-detects `railway.toml` and deploys on every push to `main`
27
+
28
+ **Option B — Railway CLI:**
29
+ ```bash
30
+ npm install -g @railway/cli
31
+ railway login
32
+ railway link
33
+ railway up
34
+ ```
35
+
36
+ ## 📖 More Info
37
+ - [Railway Docs](https://docs.railway.app)
38
+ - [Railway CLI Reference](https://docs.railway.app/reference/cli-api)
@@ -0,0 +1,16 @@
1
+ [build]
2
+ builder = "dockerfile"
3
+ dockerfilePath = "Dockerfile"
4
+
5
+ [deploy]
6
+ startCommand = "java -jar target/*.jar"
7
+ restartPolicyType = "on-failure"
8
+ restartPolicyMaxRetries = 5
9
+ healthcheckPath = "/actuator/health"
10
+ healthcheckTimeout = 100
11
+
12
+ [env]
13
+ # Add your env variables in the Railway dashboard under Variables
14
+ # DATABASE_URL =
15
+ # JWT_SECRET =
16
+ # SPRING_PROFILES_ACTIVE = "prod"
@@ -0,0 +1,14 @@
1
+ [build]
2
+ builder = "nixpacks"
3
+ buildCommand = "npm install && npm run build"
4
+
5
+ [deploy]
6
+ startCommand = "npm start"
7
+ restartPolicyType = "on-failure"
8
+ restartPolicyMaxRetries = 5
9
+
10
+ [env]
11
+ # Add your env variables in the Railway dashboard under Variables
12
+ # DATABASE_URL =
13
+ # JWT_SECRET =
14
+ # NEXTAUTH_URL =
@@ -0,0 +1,14 @@
1
+ [build]
2
+ builder = "nixpacks"
3
+ buildCommand = "npm install && npm run build"
4
+
5
+ [deploy]
6
+ startCommand = "npm start"
7
+ restartPolicyType = "on-failure"
8
+ restartPolicyMaxRetries = 5
9
+
10
+ [env]
11
+ # Add your env variables in the Railway dashboard under Variables
12
+ # DATABASE_URL =
13
+ # JWT_SECRET =
14
+ # NODE_ENV = "production"
@@ -0,0 +1,13 @@
1
+ [build]
2
+ builder = "nixpacks"
3
+ buildCommand = "pip install -r requirements.txt"
4
+
5
+ [deploy]
6
+ startCommand = "uvicorn app.main:app --host 0.0.0.0 --port $PORT"
7
+ restartPolicyType = "on-failure"
8
+ restartPolicyMaxRetries = 5
9
+
10
+ [env]
11
+ # Add your env variables in the Railway dashboard under Variables
12
+ # DATABASE_URL =
13
+ # JWT_SECRET =