This document describes how to package, test, deploy, and operate the entire Snapp ecosystem (snapp, map, food, bank, email and supporting microservices). It gives a simple development path (quick local deploy) and a production-grade path (Kubernetes, CI/CD, observability), plus testing strategy, API documentation requirements, inter-service communication options, and optional professional features.
Keep the rule: each microservice is an independently buildable repository under the
snapp-mapGitHub org. Every repo must include:Dockerfile, automated tests, OpenAPI (or proto) spec, README, and adeploy/folder with compose + k8s manifests / Helm chart.
Provide an easy path so students can run the whole system locally.
Recommend:
-
Per-service
Dockerfile. -
A top-level
docker-compose.yml(in each hub repo or a separateinfra/repo) that composes all required services for local dev: snapp services, map (or map-mock), food services, bank, email, auth mock, database containers, message broker (RabbitMQ/Redis), and an API gateway (optional).
docker-compose.yml (skeleton)
(Place in snapp-map/stack/docker-compose.yml)
version: "3.8"
services:
postgres:
image: postgres:15
environment: [ POSTGRES_USER=snapp, POSTGRES_PASSWORD=snapp, POSTGRES_DB=snapp ]
volumes: ["./data/db:/var/lib/postgresql/data"]
redis:
image: redis:7
ports: ["6379:6379"]
rabbitmq:
image: rabbitmq:3-management
ports: ["5672:5672","15672:15672"]
map-service:
build: ../../map-hub/map-service
environment: [ DATABASE_URL=postgres://... ]
depends_on: ["postgres","redis"]
snapp-user-service:
build: ../../snapp-hub/user-service
environment: [ DATABASE_URL=postgres://... ]
depends_on: ["postgres"]
# ... other services
How to run: docker-compose up --build — a single command to bring up the dev environment.
For production-style deployment use Kubernetes. Provide:
-
A Helm chart per microservice (or one umbrella chart for the whole hub).
-
Namespaces:
snapp-dev,snapp-staging,snapp-prod. -
Ingress Controller (NGINX) or API Gateway (Kong/Traefik).
-
Use
Deployment,Service,HorizontalPodAutoscaler,ConfigMap,Secret.
Kubernetes best-practices
-
Use images pushed to a registry (GitHub Packages / Docker Hub / private registry).
-
Keep secrets out of Git (use Kubernetes Secrets, sealed-secrets, or HashiCorp Vault).
-
Use resource requests/limits.
-
Use liveness & readiness probes.
-
Use rolling updates, or for safer upgrades, canary/blue-green via tooling (Argo Rollouts or service mesh).
Minimal deployment.yaml snippet
apiVersion: apps/v1
kind: Deployment
metadata: { name: map-service }
spec:
replicas: 2
selector: { matchLabels: { app: map-service } }
template:
metadata: { labels: { app: map-service } }
spec:
containers:
- name: map
image: ghcr.io/snapp-map/map-service:0.1.0
envFrom:
- secretRef: { name: map-secrets }
ports: [{ containerPort: 8000 }]
livenessProbe: ...
readinessProbe: ...
Create a standard pipeline for every microservice repository. Each pipeline should:
-
Run lint & static analysis.
-
Run unit tests -> collect coverage.
-
Build Docker image and run integration tests (optional).
-
Push image to registry (on success, on tag).
-
Deploy to staging (on merge to
main) and optional prod on tag/approval.
Example GitHub Actions (pseudo)
name: CI
on: [push, pull_request]
jobs:
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node / Java / Python / Go (per repo)
- run: ./gradlew test # or npm test / pytest / go test
- run: npm run lint
- run: coverage report
build-and-push:
needs: build-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/build-push-action@v4
with:
push: true
tags: ghcr.io/snapp-map/${{ github.repo }}:${{ github.sha }}
deploy-staging:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: azure/setup-kubectl@v3
- run: helm upgrade --install map-service ./deploy/helm --namespace snapp-staging
Notes
-
Use branch protection & required checks.
-
Use secrets for registry and kubeconfig.
-
Require manual approval for production deploys.
Testing must be part of grading. Recommend these layers:
-
Unit Tests — fast, isolated. (JUnit for Java, Jest/Mocha for Node, pytest for Python,
testingfor Go.)- Cover business logic (price calc, matching algorithms).
-
Integration Tests — service with DB and message broker (use testcontainers / docker-compose).
- Verify persistence, external API interactions (map-bank-email mocks).
-
Contract Tests — consumer-driven contracts (Pact) or verify OpenAPI/gRPC protobuf compatibility.
- Important for polyglot teams.
-
End-to-End (E2E) Tests — run against a deployed staging stack.
- Cypress / Playwright for UI (if any), Postman/Newman or REST clients for APIs.
-
Smoke Tests — quick health checks after deploy.
-
Performance Tests — k6 or Gatling for load testing critical flows (e.g., dispatch matching).
-
Security & Static Analysis
- SAST (Bandit for Python, SonarQube), dependency scanning (Dependabot, Snyk), container scanning (Trivy).
-
Chaos / Resilience Tests (optional) — test service degradation.
Grading hooks
- Each repo must run
make testand produce an artifacts folder with test coverage and a junit-style report to be collected by CI.
Documentation is required and part of the deliverable.
Musts:
-
OpenAPI (Swagger) for REST services (auto-generated). Publish
swagger.jsonin repo and a hosted Swagger UI (or at/docs). -
For gRPC services ship
.protofiles and auto-generated client stubs. -
README with:
- Purpose, quick start, endpoints, environment variables, DB migrations, how to run tests, and how to build images.
-
Architecture docs: system overview, sequence diagrams for important flows (booking, payment), service contracts.
-
ADR (Architecture Decision Records): record big decisions (why REST vs gRPC, choice of broker).
-
CHANGELOG.md and semantic versioning for each microservice.
Multiple options — choose based on use-case.
-
Synchronous HTTP REST (OpenAPI)
- Easy, human-readable, great for request/response (auth, user profile).
-
gRPC
- Good for high-throughput, low-latency RPC between polyglot services; strongly typed structs via proto files. Recommend for internal service-to-service core contracts (map → snapp).
-
Message Broker (async) — RabbitMQ / Kafka / NATS
- Use for events:
ride_requested,driver_accepted,payment_completed. Promotes resiliency and decoupling.
- Use for events:
-
Webhooks
- Useful for pushing events to external systems (or 3rd-party callbacks).
-
SDK / Client Libraries (recommended)
- Provide language-specific clients (a tiny
snapp-client-js,snapp-client-go) encapsulating auth, retries, backoff, and common DTOs. Easier for students than calling raw HTTP every time.
- Provide language-specific clients (a tiny
-
API Gateway (Kong/Tyk/Traefik) or Adapters
- Centralizes authentication, rate-limiting, request routing, and can host API docs.
Recommendation: Use REST + Events as default. Provide client SDKs (small libraries with typed request/response and retries) to simplify integration.
Production-level observability helps debugging and grading.
-
Structured logs (JSON) with fields:
timestamp,service,trace_id,level,message. -
Centralized logging: EFK/ELK (Elasticsearch + Fluentd/Logstash + Kibana) or Loki + Grafana.
-
Metrics: expose Prometheus metrics (
/metrics) and collect with Prometheus. Key metrics: request latency, error rates, queue lengths, job processing times. -
Tracing: Distributed tracing with Jaeger or Zipkin — add trace IDs to logs and propagate across services.
-
Dashboards: Grafana dashboards for latency, errors, throughput, and resource usage.
-
Use TLS for all external endpoints; for dev you may allow HTTP.
-
Store secrets in Kubernetes secrets / Vault. Never commit them.
-
Use OAuth2/JWT for service-to-service auth or mTLS (service mesh).
-
Enforce role-based access control for APIs (admin/support/driver/user scopes).
-
Use Dependency scanning, SCA, and SAST in CI.
-
Each microservice can have its own DB schema (per-service DB).
-
Use logical backups for Postgres (pg_dump), and automate snapshots.
-
For stateful data like message queues, use durable persistence or retention policies.
-
Rolling updates by default.
-
Support canary or blue/green (Argo Rollouts / Flagger) for safer releases.
-
Keep versioned APIs; support backward compatibility for a release cycle.
These are not required but great for students to explore:
-
Service Mesh (Istio/Linkerd) for mTLS, traffic shaping, observability.
-
Advanced Monitoring: anomaly detection, alerting (PagerDuty, Opsgenie).
-
Central Policy: OPA (Open Policy Agent) for authorization rules.
-
Advanced Logging: structured correlation across requests, log enrichment.
-
Autoscaling & Cost Optimization: HPA + cluster autoscaler.
-
AI features:
-
Demand forecasting (when to increase driver incentives).
-
Route optimizations learned from telemetry.
-
Smart ETA predictions using ML models.
-
Chatbot for support (NLP).
-
-
Analytics Warehouse: dump events into a data lake (ClickHouse/BigQuery) for analytics dashboards.
-
Monitoring Uptime & SLAs: SLOs, error budget reporting.
-
CI/CD elaboration: Canary deploy automation and auto-rollbacks on health checks.
For each team/repo, require the following deliverables:
-
✅
README.mdwith quick-start & architecture overview -
✅
Dockerfile+ functionaldocker-compose.ymlto run locally -
✅ Helm chart or
k8s/manifests for deployment -
✅ Unit & Integration tests with reports and coverage badge
-
✅ GitHub Actions (or equivalent) pipeline file(s) that run tests and build images
-
✅ OpenAPI spec (
openapi.yaml) or.protofiles and generated client stubs -
✅ Example
clientusage snippet (curl + sample SDK usage) -
✅ Logging format sample and
/metricsendpoint -
✅ Postman collection or automated E2E test script
-
✅ Optional: Prometheus + Grafana dashboard export for 2–3 key charts (latency, errors, throughput)
Grade weight ideas:
-
Phase 1 MVP correctness & stability — 40%
-
Tests & CI/CD — 20%
-
Documentation & API contracts — 15%
-
Deployment scripts (compose + k8s/helm) — 10%
-
Observability & extras — 10%
-
Design principles & code quality (SOLID, patterns) — 5%
-
Start with docker-compose for everything. Only graduate to Kubernetes when the MVP works.
-
Use lightweight message broker (Redis Streams or RabbitMQ) instead of full Kafka unless needed.
-
Provide pre-built mock services (map-mock, auth-mock) so teams can run core features without waiting for other teams.
-
Encourage client libraries for common contract use — faster integration and fewer mistakes.
user-service/
├─ src/
├─ tests/
├─ Dockerfile
├─ openapi.yaml
├─ README.md
├─ deploy/
│ ├─ docker-compose.yml
│ ├─ helm/
│ └─ k8s/
├─ .github/workflows/ci.yml
└─ Makefile # make build/test/runIf you’d like, I can:
-
Produce a sample GitHub Actions CI file tuned for one of the languages (e.g., Spring Boot or FastAPI).
-
Generate a starter
docker-compose.ymlthat includes the minimal set of services (Postgres, Redis, RabbitMQ, auth-mock, map-mock, snapp-user, snapp-trip). -
Create a grading rubric in checklist form for students.