A containerized microservices architecture project using Kubernetes, featuring an API service, background worker, PostgreSQL database, and Redis cache.
MiniLab is a distributed application deployed on Kubernetes with the following components:
- API Service: Express.js REST API connected to PostgreSQL
- Worker Service: Background job processor using Redis
- Database: PostgreSQL with persistent storage
- Cache: Redis for inter-service communication and caching
- Ingress: HTTP routing for external access
βββββββββββββββ
β Ingress β
ββββββββ¬βββββββ
β
ββββ΄βββ
β β
βββββΌβββ ββΌβββββββββ
β API β β Worker β
ββββ¬ββββ ββββββ¬βββββ
β β
βββββββ¬βββββ
β
ββββββΌβββββ
β Redis β
ββββββ¬βββββ
β
ββββββΌβββββββββ
β PostgreSQL β
βββββββββββββββ
- Docker & Docker Compose
- Kubernetes cluster (minikube, kind, or cloud provider)
- kubectl CLI
- Node.js 18+ (for local development)
-
Clone the repository
git clone https://github.com/your-username/minilab.git cd minilab -
Deploy to Kubernetes
# Create namespace kubectl apply -f 00-namespace.yaml # Deploy all services (in order) kubectl apply -f 0*.yaml kubectl apply -f 1*.yaml
-
Verify deployment
kubectl get pods -n minilab kubectl get svc -n minilab
project1/
βββ README.md # This file
βββ 00-namespace.yaml # Kubernetes namespace
βββ 01-postgres-secret.yaml # PostgreSQL credentials
βββ 02-postgres-pvc.yaml # Persistent volume claim
βββ 03-postgres-statefulset.yaml # PostgreSQL deployment
βββ 04-postgres-service.yaml # PostgreSQL service
βββ 05-redis-deployment.yaml # Redis deployment
βββ 06-redis-service.yaml # Redis service
βββ 07-api-configmap.yaml # API configuration
βββ 08-api-deployment.yaml # API deployment
βββ 09-api-service.yaml # API service
βββ 10-worker-deployment.yaml # Worker deployment
βββ 11-api-ingress.yaml # Ingress controller
βββ 12-postgres-networkpolicy.yaml # Network policies
βββ 13-worker-hpa.yaml # Horizontal pod autoscaling
βββ api/ # API service
β βββ Dockerfile
β βββ index.js
β βββ package.json
β βββ package-lock.json
βββ worker/ # Background worker service
βββ Dockerfile
βββ index.js
βββ package.json
βββ package-lock.json
- Framework: Express.js
- Dependencies: Express, PostgreSQL driver (pg), Redis
- Port: 3000 (configured in deployment)
- Role: REST API for client requests
- Dependencies: Redis, Cheerio (HTML parsing)
- Role: Asynchronous job processing
- Scaling: Managed by HPA (Horizontal Pod Autoscaler)
- Type: PostgreSQL (StatefulSet)
- Storage: Persistent Volume
- Credentials: Stored in Secret resource
- Type: Redis
- Role: Inter-service messaging and caching
# Install dependencies
cd api && npm install
cd ../worker && npm install
# Set up environment variables
# Create .env file with database and redis URLs# Run API service
cd api
npm start
# Run worker (in separate terminal)
cd worker
npm startEach service has a Dockerfile for containerization:
# Build API image
docker build -t minilab-api:latest ./api
# Build Worker image
docker build -t minilab-worker:latest ./worker- 00-namespace.yaml: Creates isolated
minilabnamespace - 01-postgres-secret.yaml: Database credentials (
β οΈ Use sealed-secrets or external secrets in production) - 02-postgres-pvc.yaml: Persistent storage for database
- 03-postgres-statefulset.yaml: PostgreSQL deployment with ordered pod management
- 04-postgres-service.yaml: Database service discovery
- 05-06: Redis deployment and service
- 07: API configuration (ConfigMap)
- 08-09: API deployment and service
- 10: Worker deployment
- 11: Ingress for external HTTP routing
- 12: Network policies for security
- 13: HPA for worker auto-scaling
-
β οΈ Secrets Management- β Currently: Plain text secrets in YAML
- β
Recommended: Use
sealed-secretsorexternal-secretsoperator
-
π Network Policies
- β Good: Network policies exist
- π‘ Ensure they're correctly restricting traffic
-
π« RBAC
- β Missing: Service accounts with proper RBAC rules
- β Recommended: Create least-privilege service accounts
-
Add Prometheus metrics
- Instrument API and Worker with prometheus client
- Add ServiceMonitor for Kubernetes monitoring
-
Centralized Logging
- Use ELK, Loki, or Cloud Logging
- Structure logs as JSON for better parsing
-
Health Checks
- Add
/healthendpoint to API - Implement readiness and liveness probes in deployments
- Add
- Replace plain-text secrets with sealed-secrets
- Add resource requests/limits
- Implement health checks and probes
- Add logging and monitoring
- Set up proper CI/CD pipeline
- Use image registry (Docker Hub, ECR, GCR)
- Enable HTTPS/TLS on Ingress
- Add backup strategy for database
# Apply all manifests
kubectl apply -f .
# Monitor deployment
kubectl rollout status deployment/api -n minilab
kubectl rollout status deployment/worker -n minilab
# Check logs
kubectl logs -f deployment/api -n minilab
kubectl logs -f deployment/worker -n minilab# Check pod status
kubectl get pods -n minilab -o wide
# View pod logs
kubectl logs <pod-name> -n minilab
# Describe pod for events
kubectl describe pod <pod-name> -n minilab
# Port forward to test locally
kubectl port-forward svc/api 3000:3000 -n minilab
# Test API endpoint
curl http://localhost:3000/health- Add
.gitignorefile - Add
.dockerignorefiles - Document environment variables
- Implement health check endpoints
- Add request/response validation
- Add error handling and logging
- Add database migrations
- Implement API authentication/authorization
- Add unit and integration tests
- Set up CI/CD pipeline (GitHub Actions)
- Add prometheus metrics
- Configure resource limits and requests
- Add API documentation (Swagger/OpenAPI)
- Implement distributed tracing (Jaeger)
- Add service mesh (Istio) for advanced routing
- Multi-stage Docker builds for optimization
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
David ABBOUD
- Email: me@abbouddavid.com
- GitHub: @davidabboud