A reference implementation of a TypeScript Express REST API demonstrating patterns and practices for CI/CD with Harness, Kubernetes deployment, and modern Node.js development. Intended for learning and adaptation, not direct production use.
- TypeScript with strict mode for type safety
- Express.js REST API with CRUD operations
- Structured logging with Pino (JSON format)
- Health checks for Kubernetes probes (liveness, readiness, startup)
- Input validation with Joi
- Security hardening with Helmet and CORS
- Comprehensive testing with Jest (70%+ coverage)
- Docker optimization with multi-stage builds (<200MB image)
- Kubernetes ready with deployment manifests
- CI/CD pipelines for Harness (build and deploy)
- Node.js 22+
- npm 10+
- Docker (optional)
- kubectl (optional)
- hadolint (optional, for Dockerfile linting)
# Install dependencies
npm install
# Copy environment variables
cp .env.example .env
# Run in development mode (with hot reload)
npm run dev
# Test the API
curl http://localhost:3000/health/live
curl http://localhost:3000/api/v1/items# Run all tests with coverage
npm test
# Run tests in watch mode
npm run test:watch
# Run only integration tests
npm run test:integration# Type checking
npm run type-check
# Linting
npm run lint
npm run lint:fix
# Formatting
npm run format:check
npm run format# Build TypeScript
npm run build
# Run production build
npm startGET /health/live- Liveness probe (always returns 200)GET /health/ready- Readiness probe (checks dependencies)GET /health/startup- Startup probe (checks if app is initialized)
GET /api/v1/items- List all itemsGET /api/v1/items/:id- Get item by IDPOST /api/v1/items- Create new itemPUT /api/v1/items/:id- Update itemDELETE /api/v1/items/:id- Delete item
# List items
curl http://localhost:3000/api/v1/items
# Get item by ID
curl http://localhost:3000/api/v1/items/1
# Create item
curl -X POST http://localhost:3000/api/v1/items \
-H "Content-Type: application/json" \
-d '{"name":"New Item","description":"Item description"}'
# Update item
curl -X PUT http://localhost:3000/api/v1/items/1 \
-H "Content-Type: application/json" \
-d '{"name":"Updated Name"}'
# Delete item
curl -X DELETE http://localhost:3000/api/v1/items/1npm run docker:buildnpm run docker:run
# Or manually:
docker run -p 3000:3000 -e NODE_ENV=production reference-api:local# Check image size (should be ~150-200MB)
docker images reference-api:local
# Test container
curl http://localhost:3000/health/live# Apply manifests
npm run k8s:apply
# Check deployment
kubectl rollout status deployment/reference-api
kubectl get pods -l app=reference-api
# Port forward
kubectl port-forward service/reference-api-service 3000:80
# Test
curl http://localhost:3000/health/live
# View logs
kubectl logs -l app=reference-api --tail=50 -f
# Cleanup
npm run k8s:deleteSee k8s/README.md for detailed Kubernetes deployment instructions.
This project includes pre-configured Harness pipelines for automated CI/CD:
- Runs linting, testing, and type checking in parallel
- Builds optimized Docker image
- Pushes to container registry with multiple tags
- Sends Slack notifications
- Deploys to Kubernetes with rolling updates
- Verifies health checks automatically
- Runs smoke tests
- Automatic rollback on failure
- Approval gates for production
See .harness/README.md for detailed Harness setup instructions.
reference-architecture-node/
├── src/
│ ├── index.ts # Application entry point
│ ├── app.ts # Express app configuration
│ ├── config/ # Configuration management
│ ├── middleware/ # Express middleware
│ ├── routes/ # API routes
│ ├── services/ # Business logic
│ └── types/ # TypeScript type definitions
├── tests/
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── k8s/ # Kubernetes manifests
├── .harness/ # Harness pipelines
├── docs/ # Documentation
├── Dockerfile # Multi-stage Docker build
└── package.json # Project dependencies
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 3000 |
NODE_ENV |
Environment (development/production) | development |
LOG_LEVEL |
Logging level (debug/info/warn/error) | info |
CORS_ORIGIN |
CORS allowed origins | * |
See .env.example for all available variables.
| Script | Description |
|---|---|
npm run dev |
Start development server with hot reload |
npm run build |
Build TypeScript to JavaScript |
npm start |
Start production server |
npm test |
Run tests with coverage |
npm run lint |
Check code quality |
npm run lint:fix |
Fix linting issues |
npm run format |
Format code with Prettier |
npm run type-check |
Type check without building |
npm run docker:build |
Build Docker image |
npm run docker:run |
Run Docker container |
npm run k8s:apply |
Deploy to Kubernetes |
npm run k8s:delete |
Remove from Kubernetes |
- Node.js 22 (Alpine)
- TypeScript 5.2+
- Express.js - Web framework
- Pino - Structured logging
- Joi - Schema validation
- Helmet - Security headers
- CORS - Cross-origin resource sharing
- Jest - Test framework
- Supertest - HTTP assertions
- ts-jest - TypeScript support for Jest
- ESLint - Linting
- Prettier - Code formatting
- Husky - Git hooks
- lint-staged - Pre-commit checks
- Docker - Containerization
- Kubernetes - Orchestration
- Harness - CI/CD platform
TypeScript provides compile-time type safety, better IDE support, and catches errors before runtime. It's the industry standard for professional Node.js applications.
Reduces final image size by 85% (from ~1GB to ~150MB) by excluding build dependencies and development tools from the production image.
Kubernetes requires different probe behaviors:
- Startup: One-time check that app has initialized
- Readiness: Can app serve traffic right now?
- Liveness: Is app still running or should it be restarted?
This is a reference architecture focused on deployment and CI/CD patterns, not database management. In-memory storage keeps the demo simple while showcasing all the important infrastructure patterns.
- Image Size: ~150-200MB (compressed)
- Memory Usage: ~128MB (runtime)
- CPU Usage: ~100m (0.1 CPU cores)
- Startup Time: ~2 seconds
- Response Time: <10ms (health checks)
- Non-root user in Docker container
- Read-only root filesystem support
- Security headers via Helmet
- CORS configuration
- Input validation
- No secrets in code or logs
- Dropped Linux capabilities
Target: 70%+ coverage across:
- Unit tests for business logic
- Integration tests for API endpoints
- Health check verification
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details
For issues and questions:
- Open an issue on GitHub
- Review the documentation in
/docs - Check .harness/README.md for Harness-specific help
Potential future enhancements:
- PostgreSQL database integration
- Redis caching layer
- JWT authentication
- Swagger/OpenAPI documentation
- Prometheus metrics
- OpenTelemetry tracing
- Rate limiting
- GraphQL API