Skip to content

About

Microservices-based e-commerce platform with a Spring Boot backend and Angular frontend.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

ecom-platform

Microservices-based e-commerce platform with a Spring Boot backend and Angular frontend.

Architecture

Backend services:

  • discovery-service (Eureka service registry)
  • gateway-service (single entrypoint, JWT auth, routing)
  • user-service (auth + profile)
  • product-service (catalog management)
  • media-service (image upload + media metadata)

Supporting infrastructure:

  • MongoDB
  • MinIO (object storage)
  • Kafka (product deletion events and asynchronous media cleanup)

Frontend:

  • Angular app consuming gateway APIs

Service docs

  • backend/discovery-service/README.md
  • backend/gateway-service/README.md
  • backend/user-service/README.md
  • backend/product-service/README.md
  • backend/media-service/README.md
  • docs/backend-unit-testing-guide.md (JUnit + backend testing walkthrough)
  • frontend/README.md
  • docs/frontend-unit-testing-guide.md (Jasmine/Karma frontend testing walkthrough)
  • docs/jenkins-guide.md (Jenkins setup + CI pipeline walkthrough)
  • docs/sonarqube-guide.md (SonarQube setup + Jenkins quality gate walkthrough)
  • docs/ghcr-deployment-guide.md (GHCR image deployment + rollback walkthrough)
  • docs/kafka-events.md (cleanup event contracts and local topic setup)

Config files

  • .env.local contains host-local values for manually running Spring services.
  • .env contains Docker-network values for both application Compose files and SonarQube.
  • .release.env is generated by CI and contains only IMAGE_REGISTRY and IMAGE_TAG.
  • .env.local.example and .env.example are the committed, secret-free templates.
  • Mongo logical DB isolation uses:
    • MONGO_USER_DATABASE
    • MONGO_PRODUCT_DATABASE
    • MONGO_MEDIA_DATABASE on the same MongoDB instance.

Prerequisites

  • Docker + Docker Compose
  • OpenSSL
  • Java 21
  • Node.js + npm

One-time setup

1) Generate gateway TLS certs (for HTTPS gateway)

mkdir -p backend/certs
openssl req -x509 -nodes -newkey rsa:2048 -sha256 -days 825 \
  -keyout backend/certs/gateway.key \
  -out backend/certs/gateway.crt \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
openssl pkcs12 -export \
  -out backend/certs/gateway.p12 \
  -inkey backend/certs/gateway.key \
  -in backend/certs/gateway.crt \
  -name gateway \
  -passout pass:changeit

2) Generate JWT RSA keys (user-service signs, gateway verifies)

mkdir -p backend/keys
openssl genpkey -algorithm RSA -out backend/keys/private.pem -pkeyopt rsa_keygen_bits:2048
openssl pkey -in backend/keys/private.pem -pubout -out backend/keys/public.pem

Launch modes

Production mode (published images)

Provision .env from .env.example and provide .release.env with the published image coordinates.

From repo root:

docker compose --env-file .env --env-file .release.env -f docker-compose.yml pull
docker compose --env-file .env --env-file .release.env -f docker-compose.yml up -d --remove-orphans

This starts backend services plus the Dockerized frontend on https://localhost:4200.

Stop:

docker compose --env-file .env --env-file .release.env -f docker-compose.yml down

Stop and remove volumes:

docker compose --env-file .env --env-file .release.env -f docker-compose.yml down -v

Full development stack (Dockerfile builds)

make dev-up

Stop the stack with make dev-down, or use make dev-down-v to also remove volumes.

Both Compose files use the pinned community build pgsty/minio:RELEASE.2026-08-04T00-00-00Z. The previously configured quay.io/minio/minio:latest image is no longer publicly pullable. This replacement is published by PGSTY, an independent MinIO fork; upstream MinIO now documents source-only distribution. The existing MinIO service name, ports, credentials, and data volume are retained.

Infrastructure-only development

  1. Start infra (mongo, minio, discovery-service, kafka) from repo root:
make dev-infra-up

To start only Kafka, run make kafka-up. Inspect it with make kafka-logs or list topics with make kafka-topics.

Kafka uses the official apache/kafka:4.3.1 image in single-node KRaft mode, with persistent storage and a health check. Docker services connect to kafka:9092; services running from the IDE connect to localhost:29092. Set KAFKA_BOOTSTRAP_SERVERS accordingly in .env and .env.local when adding the service producers and consumers. Topic auto-creation is disabled. Product service creates product.events and User service creates user.events at application startup using Spring Kafka NewTopic beans. Existing topics are reused. Start Kafka before either application; startup fails if Kafka is unavailable. make kafka-up starts only the broker. See Kafka events for the event payloads.

Product deletion publishing and Media cleanup are implemented. Production Compose also includes a single broker accessible on the backend network. Product deletion, detached-image cleanup, and avatar replacement/clearing cleanup are implemented. The kafka-data volume preserves broker state; make dev-down-v removes it along with the other development volumes.

  1. Run backend services manually (each in a separate terminal). Start product and user services first so they create the topics consumed by media service:
cd backend/product-service && ./mvnw spring-boot:run
cd backend/user-service && ./mvnw spring-boot:run
cd backend/media-service && ./mvnw spring-boot:run
cd backend/gateway-service && ./mvnw spring-boot:run
  1. Run frontend:
cd frontend
npm install
npm run start:https
  1. Stop infra:
make dev-infra-down

In this mode, manually launched backend services load host-local values from root .env.local. Frontend in dev mode still runs manually with npm run start:https.

Main URLs

  • Frontend: https://localhost:4200
  • Gateway: https://localhost:8443
  • Eureka: http://localhost:8761
  • MinIO API: http://localhost:9000
  • MinIO Console: http://localhost:9001
  • SonarQube: http://localhost:9002

API flow notes

Auth and profile avatar

  1. POST /auth/register
  2. Optional avatar upload: POST /media/profile
  3. Link avatar to profile: PATCH /users/me with avatarMediaId

Product and images

  1. Create product: POST /products with mediaIds: []
  2. Upload images: POST /media/images with productId + files[]
  3. Save image IDs on product: PUT /products/{id} with mediaIds

User and product discover media service through Eureka with explicit HTTP timeouts; MEDIA_SERVICE_BASE_URL is no longer needed. Avatar uploads preserve previous images until a profile change publishes USER_AVATAR_CHANGED to clean up the previous avatar. Product image metadata is available at GET /media/images/{productId}; the browser loads returned object URLs through Gateway → MinIO.

Product uploads verify ownership through an internal product-service endpoint before validating files. Media discovers product service through Eureka using Spring Cloud LoadBalancer; a fixed PRODUCT_SERVICE_BASE_URL is no longer required. Media accepts JPEG and PNG using Apache Tika content type detection and ImageIO decoding checks; GIF and WebP are unsupported. Deploy product service before media service when introducing this ownership check. See the media-service README for upload failure and cleanup behavior.

Compose files

  • docker-compose.dev.yml builds the complete application from local Dockerfiles.
  • docker-compose.yml runs immutable images selected by .release.env.
  • Jenkins and SonarQube retain their tool-specific Compose files.
  • Frontend Docker runtime uses Nginx with TLS certs from backend/certs and proxies API routes to gateway-service.

About

Microservices-based e-commerce platform with a Spring Boot backend and Angular frontend.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages