Monorepo containing a Next.js frontend and a Spring Boot backend packaged with Gradle. A local Docker Compose setup runs a full stack (API, DB, cache, MQ, frontend) with minimal friction.
An online coffee shop where customers can browse products, build a cart, and place orders with secure payments and delivery options. The system sends transactional emails and supports OAuth sign‑in for a smooth checkout.
- Frontend: Next.js app (Turbopack in dev) at
http://localhost:3000. - Backend: Spring Boot app (module
integration) exposing REST API athttp://localhost:8080/api/v1. - Infrastructure: Postgres (catalog/orders), Redis (caching, rate limits), RabbitMQ (async jobs/email).
- Product browsing: view coffee products with details; supports a modern, responsive UI.
- Cart and reservations: items reserved briefly during checkout (configurable TTL).
- Checkout and payments: integrates with Stripe for payments; success/cancel flows configurable.
- Delivery options: shipping rate IDs are configurable for supported destinations.
- Email notifications: Mailjet integration for order confirmations and other emails.
- Authentication: JWT‑based auth with refresh tokens; Google OAuth optional.
- Security: brute‑force protection and sane cookie defaults for local/dev.
Requirements: Docker and Docker Compose
- Copy env file
cp .env.example .env
# Edit .env and set real secrets for JWT/Stripe/Google/Mailjet as needed- Build and start
docker compose up -d --build- Open the apps
- Frontend: http://localhost:3000
- Backend health: http://localhost:8080/api/v1/health
Notes
- Only API (8080) and Frontend (3000) are exposed to the host. Postgres, Redis, and RabbitMQ are available only on the internal Docker network
swe_app_net. - The backend runs with the
dockerSpring profile and connects to services by container DNS names:postgresql-group9,redis-group9,rabbitmq-group9. - The frontend image runs
next devfor a fast dev experience inside Docker.
Useful commands
docker compose logs -f app # Tail backend logs
docker compose logs -f frontend # Tail frontend logs
docker compose down # Stop stackYou can run infra via Docker and the apps locally for faster iteration.
- Start infra only
docker compose up -d postgresql redis rabbitmq- Run backend locally
cd backend
./gradlew :integration:bootRun
# Uses 'local' profile by default; points to localhost unless overridden via env- Run frontend locally
cd frontend
npm ci
npm run dev:local
# or: NEXT_PUBLIC_API_BASE_URL=http://localhost:8080/api/v1 npm run dev.
├── backend/ # Spring Boot (Gradle multi-module)
│ ├── integration/ # API application module
│ │ └── src/main/resources/
│ │ ├── application-local.yml
│ │ ├── application-docker.yml
│ │ └── application-deploy.yml
│ └── docker/
│ ├── Dockerfile # Production image (profile=deploy)
│ └── Dockerfile.dev # Dev image (profile configurable)
├── frontend/ # Next.js 15 app
│ ├── Dockerfile # Dev-oriented (runs next dev)
│ ├── package.json
│ └── src/
├── docker-compose.yml # Local stack (DB/cache/MQ/API/frontend)
├── .env.example # Copy to .env and customize
└── README.md
Set variables in .env (see .env.example). Key values:
- Frontend
NEXT_PUBLIC_API_BASE_URL– Browser calls to the API (defaulthttp://localhost:8080/api/v1).NEXT_PUBLIC_ENVIRONMENT– Display/env indicator for the UI.
- Database
POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB– Postgres credentials.
- RabbitMQ
RABBITMQ_USERNAME,RABBITMQ_PASSWORD– Credentials.
- Email (Mailjet)
MAILJET_API_KEY,MAILJET_API_SECRET,MAIL_FROM_EMAIL,MAIL_FROM_NAME.
- Backend secrets
JWT_SECRET– HMAC secret for signing JWTs.STRIPE_API_KEY,STRIPE_WEBHOOK_SECRET– Payments.GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_REDIRECT_URI– OAuth.
Runtime profiles
- Backend dev image defaults to
SPRING_PROFILES_ACTIVE=docker(configured inbackend/docker/Dockerfile.dev). - You can override by setting
SPRING_PROFILES_ACTIVEon theappservice indocker-compose.yml.
- Umbrella:
.github/workflows/Deploy-Umbrella.ymlorchestrates deployments, calling backend and frontend deploy workflows when triggered.
- Backend deploy (
deploy-backend.yml):- Builds and tests with Gradle, then builds and pushes a Docker image to GitHub Container Registry
ghcr.io/<org>/StackOverFlowedCup-API. - Signs the image with cosign (keyless via OIDC).
- SSHes into a remote host and performs blue/green deploy via Docker Compose and Kong for gradual traffic shift.
- Required repository SECRETS:
SSH_PRIVATE_KEY– private key for the deploy user.SERVER_USER,SERVER_IP– SSH target.
- Required repository VARS:
APP_DIR– absolute path to the app’s folder on the server (git repo is pulled here).DOCKER_COMPOSE_FILE– absolute path to the compose file on server (e.g.backend/docker/compose.bluegreen.yml).KONG_ADMIN_URL– Kong Admin API upstream targets base URL.BLUE_PORT,GREEN_PORT– ports used by blue/green services (match compose file).
- Builds and tests with Gradle, then builds and pushes a Docker image to GitHub Container Registry
- Frontend deploy (
deploy-frontend.yml):- Builds the Next.js app with Node 20, then uses Vercel CLI to deploy production build.
- Required repository SECRETS:
VERCEL_ORG_ID,VERCEL_PROJECT_ID,VERCEL_TOKEN.
- Pull request workflows:
- Backend: compile, test, coverage report, dependency updates, CodeQL (
pull-request-backend.yml). - Frontend: install, build, and Vercel Preview deploy (
pull-request-frontend.yml).
- Backend: compile, test, coverage report, dependency updates, CodeQL (
- Install Docker and Docker Compose; ensure the deploy user can run
sudo docker. - Clone this repo into
APP_DIRand keeporiginpointing to GitHub (workflow runsgit pull origin main). - Ensure the external Docker network used in
backend/docker/compose.bluegreen.ymlexists (e.g.,docker network create bushive_network). - Create
backend/.envon the server with production values referenced by the compose file (env_file: ../.env). - Kong configured with two upstream targets, e.g.,
swe-backend-blueandswe-backend-green, reachable onBLUE_PORT/GREEN_PORT.
Triggering deployments
- From GitHub → Actions → run “Deploy Umbrella”, or trigger individual backend/frontend deploy workflows with “Run workflow”.
- Image tags: the backend workflow tags/pushes to GHCR using the standard Docker metadata-action strategy based on the branch/ref.
Build a production image using the provided Dockerfile:
docker build -f backend/docker/Dockerfile -t app-backend:prod ./backend
docker run -p 8080:8080 \
-e DB_URL="jdbc:postgresql://<db-host>:5432/<db-name>" \
-e DB_USERNAME=<user> -e DB_PASSWORD=<pass> \
-e JWT_SECRET=<secret> \
app-backend:prodThe prod image uses the deploy Spring profile; configure DB/Redis/RabbitMQ and other secrets via env variables or your orchestrator’s secret manager.
Option A — Node process (e.g., behind Nginx/ingress):
cd frontend
npm ci
NEXT_PUBLIC_API_BASE_URL=https://api.example.com/api/v1 \
NEXT_PUBLIC_ENVIRONMENT=prod \
npm run build
npm run start -- -p 3000Option B — Containerize a prod image (recommended): create a multi-stage Dockerfile that runs next build and next start, or adapt the existing dev Dockerfile to a production target. Ensure NEXT_PUBLIC_* variables are provided at build-time.
- Place Postgres/Redis/RabbitMQ on internal networks; expose only the API and frontend.
- Provide secrets via your platform (Docker secrets, Kubernetes Secrets, etc.).
- DB connection to
localhost:5432in Docker: ensure the backend runs with thedockerprofile and thatapplication-docker.ymlpoints to your DB service hostname. - Frontend can’t reach API: verify
NEXT_PUBLIC_API_BASE_URLmatches your API base URL and the container/host port mapping. - LightningCSS native binding errors in frontend: the dev image sets
LIGHTNINGCSS_*to prefer WASM; keep these if your platform lacks native bindings.