-
Notifications
You must be signed in to change notification settings - Fork 0
Cloud-native MEAN boilerplate #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| root = true | ||
|
|
||
| [*] | ||
| indent_style = space | ||
| indent_size = 2 | ||
| end_of_line = lf | ||
| charset = utf-8 | ||
| trim_trailing_whitespace = true | ||
| insert_final_newline = true | ||
|
|
||
| [*.md] | ||
| trim_trailing_whitespace = false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # ============================================== | ||
| # MEAN Cloud-Native Boilerplate — Environment | ||
| # ============================================== | ||
| # Copy this file to `.env` and fill in real values. | ||
|
|
||
| # --- MongoDB --- | ||
| MONGO_PORT=27017 | ||
| MONGO_USERNAME=admin | ||
| MONGO_PASSWORD=password | ||
| MONGO_DATABASE=mean_app | ||
|
|
||
| # --- Backend --- | ||
| BACKEND_PORT=3000 | ||
| NODE_ENV=development | ||
| JWT_SECRET=change-me-to-a-random-string | ||
| JWT_EXPIRATION=1h | ||
| CORS_ORIGIN=http://localhost:4200 | ||
| LOG_LEVEL=debug | ||
|
|
||
| # --- Frontend --- | ||
| FRONTEND_PORT=4200 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| name: CI Pipeline | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, develop] | ||
| pull_request: | ||
| branches: [main, develop] | ||
|
|
||
| env: | ||
| NODE_VERSION: '20' | ||
|
|
||
| jobs: | ||
| backend: | ||
| name: Backend — Lint, Test & Build | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: backend | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ env.NODE_VERSION }} | ||
| cache: npm | ||
| cache-dependency-path: backend/package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Lint | ||
| run: npm run lint | ||
|
|
||
| - name: Type check | ||
| run: npx tsc --noEmit | ||
|
|
||
| - name: Test | ||
| run: npm test | ||
|
|
||
| - name: Build | ||
| run: npm run build | ||
|
|
||
| frontend: | ||
| name: Frontend — Build | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: frontend | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ env.NODE_VERSION }} | ||
| cache: npm | ||
| cache-dependency-path: frontend/package-lock.json | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Build | ||
| run: npx ng build --configuration production | ||
|
|
||
| docker: | ||
| name: Docker Build Verification | ||
| runs-on: ubuntu-latest | ||
| needs: [backend, frontend] | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Build backend Docker image | ||
| run: docker build --target production -t mean-backend:ci ./backend | ||
|
|
||
| - name: Build frontend Docker image | ||
| run: docker build --target production -t mean-frontend:ci ./frontend |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| node_modules/ | ||
| dist/ | ||
| build/ | ||
| coverage/ | ||
| .env | ||
| .env.local | ||
| *.log | ||
| .DS_Store | ||
| .angular/ | ||
| .vscode/ | ||
| *.tgz | ||
| .nyc_output/ | ||
| tmp/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| npx --no -- commitlint --edit $1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| npx lint-staged |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| node_modules | ||
| dist | ||
| build | ||
| coverage | ||
| .angular | ||
| .next |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "semi": true, | ||
| "trailingComma": "all", | ||
| "singleQuote": true, | ||
| "printWidth": 100, | ||
| "tabWidth": 2, | ||
| "endOfLine": "lf", | ||
| "arrowParens": "always", | ||
| "bracketSpacing": true | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,138 @@ | ||
| # mean-boilerplate | ||
| # Cloud-Native MEAN Stack Boilerplate | ||
|
|
||
| A production-ready, cloud-native MEAN (MongoDB, Express.js, Angular, Node.js) boilerplate built with **TypeScript** and following the **12-Factor App** methodology. | ||
|
|
||
| ## Tech Stack | ||
|
|
||
| | Layer | Technology | | ||
| | ---------- | ---------------------------------------------- | | ||
| | Database | MongoDB 7 + Mongoose ODM | | ||
| | Backend | Node.js 20+ / Express.js / TypeScript (Strict) | | ||
| | Frontend | Angular 19 / Standalone Components / Signals | | ||
| | Containers | Docker multi-stage builds / Docker Compose | | ||
| | CI/CD | GitHub Actions | | ||
|
|
||
| ## Project Structure | ||
|
|
||
| ``` | ||
| ├── backend/ | ||
| │ ├── src/ | ||
| │ │ ├── config/ # Env validation (Zod), DB connection | ||
| │ │ ├── middleware/ # Error handler, validation, not-found | ||
| │ │ ├── modules/ | ||
| │ │ │ ├── auth/ # JWT auth (register, login, middleware) | ||
| │ │ │ ├── health/ # Liveness & readiness probes | ||
| │ │ │ └── users/ # CRUD user management | ||
| │ │ ├── utils/ # Logger (Pino), AppError, response helpers | ||
| │ │ ├── app.ts # Express app factory | ||
| │ │ └── server.ts # Bootstrap & graceful shutdown | ||
| │ ├── tests/ # Jest unit & integration tests | ||
| │ └── Dockerfile # Multi-stage (dev + prod) | ||
| ├── frontend/ | ||
| │ ├── src/ | ||
| │ │ ├── app/ | ||
| │ │ │ ├── core/ # Auth service, interceptors, guards | ||
| │ │ │ ├── features/ # Home, Auth (login/register), Dashboard | ||
| │ │ │ └── shared/ # Models, shared components | ||
| │ │ ├── environments/ # Dev & prod environment configs | ||
| │ │ └── styles/ # Global SCSS | ||
| │ ├── nginx.conf # Production Nginx config | ||
| │ └── Dockerfile # Multi-stage (dev + Nginx prod) | ||
| ├── .github/workflows/ci.yml # CI pipeline | ||
| ├── docker-compose.yml # Full stack local development | ||
| └── .husky/ # Git hooks (commitlint, lint-staged) | ||
| ``` | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| - Node.js >= 20 | ||
| - Docker & Docker Compose | ||
| - npm >= 10 | ||
|
|
||
| ### Development with Docker (Recommended) | ||
|
|
||
| ```bash | ||
| cp .env.example .env | ||
| docker compose up --build | ||
| ``` | ||
|
|
||
| | Service | URL | | ||
| | -------- | ------------------------- | | ||
| | Frontend | http://localhost:4200 | | ||
| | Backend | http://localhost:3000 | | ||
| | MongoDB | mongodb://localhost:27017 | | ||
|
|
||
| ### Local Development (without Docker) | ||
|
|
||
| ```bash | ||
| # Install all dependencies | ||
| npm install | ||
|
|
||
| # Start backend (requires MongoDB running) | ||
| npm run dev:backend | ||
|
|
||
| # Start frontend (in another terminal) | ||
| npm run dev:frontend | ||
| ``` | ||
|
|
||
| ## API Endpoints | ||
|
|
||
| ### Health Checks | ||
|
|
||
| | Method | Endpoint | Description | | ||
| | ------ | ------------------- | ------------------------------------ | | ||
| | GET | `/health/liveness` | Process is running | | ||
| | GET | `/health/readiness` | App can serve traffic (DB connected) | | ||
|
|
||
| ### Auth | ||
|
|
||
| | Method | Endpoint | Description | | ||
| | ------ | -------------------- | ----------------- | | ||
| | POST | `/api/auth/register` | Register new user | | ||
| | POST | `/api/auth/login` | Login | | ||
| | GET | `/api/auth/profile` | Get current user | | ||
|
|
||
| ### Users (Authenticated) | ||
|
|
||
| | Method | Endpoint | Description | | ||
| | ------ | ---------------- | ------------------ | | ||
| | GET | `/api/users` | List users (paged) | | ||
| | GET | `/api/users/:id` | Get user by ID | | ||
| | PATCH | `/api/users/:id` | Update user | | ||
| | DELETE | `/api/users/:id` | Soft-delete user | | ||
|
|
||
| ## Testing | ||
|
|
||
| ```bash | ||
| # Backend tests | ||
| cd backend && npm test | ||
|
|
||
| # Frontend tests (requires Chrome/Chromium) | ||
| cd frontend && npm test | ||
| ``` | ||
|
|
||
| ## Code Quality | ||
|
|
||
| - **ESLint** + **Prettier** for consistent formatting | ||
| - **Husky** pre-commit hooks run lint-staged | ||
| - **Commitlint** enforces Conventional Commits (`feat:`, `fix:`, etc.) | ||
| - **TypeScript Strict Mode** across the entire stack | ||
|
|
||
| ## Security | ||
|
|
||
| - **Helmet** for HTTP security headers | ||
| - **CORS** configured per environment | ||
| - **Rate limiting** on API routes (100 req / 15 min) | ||
| - **bcrypt** password hashing (12 salt rounds) | ||
| - **JWT** bearer token authentication | ||
| - **Zod** request validation | ||
|
|
||
| ## Environment Variables | ||
|
|
||
| See `.env.example` for all configuration options. The backend validates all required environment variables at startup using Zod — the server will refuse to start with invalid config. | ||
|
|
||
| ## License | ||
|
|
||
| MIT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| node_modules | ||
| dist | ||
| coverage | ||
| .env | ||
| .env.local | ||
| *.log | ||
| .git |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # ============================================== | ||
| # Backend Environment Variables | ||
| # ============================================== | ||
| NODE_ENV=development | ||
| PORT=3000 | ||
|
|
||
| # --- MongoDB --- | ||
| MONGO_URI=mongodb://admin:password@localhost:27017/mean_app?authSource=admin | ||
|
|
||
| # --- JWT --- | ||
| JWT_SECRET=change-me-to-a-random-string | ||
| JWT_EXPIRATION=1h | ||
|
|
||
| # --- CORS --- | ||
| CORS_ORIGIN=http://localhost:4200 | ||
|
|
||
| # --- Logging --- | ||
| LOG_LEVEL=debug |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # ============================================ | ||
| # Stage 1: Base image with dependencies | ||
| # ============================================ | ||
| FROM node:20-alpine AS base | ||
| WORKDIR /app | ||
| COPY package.json package-lock.json* ./ | ||
| RUN npm ci --ignore-scripts | ||
| COPY . . | ||
|
|
||
| # ============================================ | ||
| # Stage 2: Development (hot-reload with tsx) | ||
| # ============================================ | ||
| FROM base AS development | ||
| ENV NODE_ENV=development | ||
| EXPOSE 3000 | ||
| CMD ["npm", "run", "dev"] | ||
|
|
||
| # ============================================ | ||
| # Stage 3: Build the TypeScript source | ||
| # ============================================ | ||
| FROM base AS build | ||
| RUN npm run build | ||
|
|
||
| # ============================================ | ||
| # Stage 4: Production-optimized image | ||
| # ============================================ | ||
| FROM node:20-alpine AS production | ||
| WORKDIR /app | ||
| ENV NODE_ENV=production | ||
|
|
||
| RUN addgroup -g 1001 -S appgroup && \ | ||
| adduser -S appuser -u 1001 -G appgroup | ||
|
|
||
| COPY package.json package-lock.json* ./ | ||
| RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force | ||
|
|
||
| COPY --from=build /app/dist ./dist | ||
|
|
||
| USER appuser | ||
| EXPOSE 3000 | ||
|
|
||
| HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ | ||
| CMD wget --quiet --tries=1 --spider http://localhost:3000/health/liveness || exit 1 | ||
|
|
||
| CMD ["node", "dist/server.js"] | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To improve Docker layer caching and optimize build times, it's recommended to separate the dependency installation from copying the application source code. The current
basestage bundles them, causing the cache to be invalidated on any source code change.By creating a
dependenciesstage that only handlesnpm ci, and then havingdevelopmentandbuildstages copy the source code, you ensure that dependencies are only re-installed whenpackage.jsonorpackage-lock.jsonchanges.