Docker Compose
Dockerfile
Spring Boot Services
It is the same Dockerfile for all 5 services.
# ---------- Stage 1: Build ----------
FROM maven:3.9.11-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# ---------- Stage 2: Run ----------
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY /app/target/*.jar token-generator.jar
ENTRYPOINT ["java", "-jar", "token-generator.jar"]
React SPA
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine
# Build output goes into .../react-ui
COPY /app/build /usr/share/nginx/html/react-ui
COPY nginx.conf /etc/nginx/conf.d/default.conf
With the following nginx.conf
server {
listen 4001;
server_name _;
# Serve files from here
root /usr/share/nginx/html;
# Debug header to confirm we hit this server
add_header X-Spa-Debug "nginx-react-ui" always;
# Exact: /react-ui (no trailing slash)
# Serve index.html directly, no redirect, no internal rewrite
location = /react-ui {
try_files /react-ui/index.html =404;
}
# Prefix: /react-ui/ (assets + SPA routes)
# Try static files, then fall back to SPA index
location ^~ /react-ui/ {
try_files $uri $uri/ /react-ui/index.html;
}
# Safety: don’t emit absolute Location headers for any internal rewrites
absolute_redirect off;
}
Docker Compose Configuration
I managed to put together a Docker Compose configuration. The one important thing to remember: replace localhost
with the container
name for all inter-service communication.
The one exception
When your application needs to send the user’s browser to a new URL (like during an OAuth redirect), Docker container names won’t work. Browsers are outside Docker’s private network and can’t resolve container names. Here, you must use a valid host address such as:
http://localhost:7080/...
(when testing locally), or- your actual server’s hostname/domain in production.
Rule of thumb
- Service ↔ Service (inside Docker): use container names (e.g.,
mysql
,registration
,bff
). - Browser ↔ App (outside Docker): use hostnames (
localhost
, or your domain).
Following this simple rule ensures your services talk to the right neighbors and your users can still access your app correctly.
As an example the bff/REACT_URI: http://localhost:7080/react-ui keeps localhost
since it is a redirection url.
docker-compose.yml
gist link of of the file: https://gist.github.com/Mehdi-HAFID/97ce26dde39ef0a4e662e5235a2ec951
services:
mysql:
image: mysql:9.4
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 'CcmN*`6@3T9H%P#yg^V<7v'
MYSQL_DATABASE: identity_hub
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: [ "CMD-SHELL", "mysqladmin ping -h localhost -uroot -p\"$MYSQL_ROOT_PASSWORD\" || exit 1" ]
interval: 5s
timeout: 2s
retries: 5
networks:
- nidam-net
registration:
build:
context: ./registration
dockerfile: Dockerfile
container_name: registration
ports:
- "4000:4000"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/identity_hub?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 'CcmN*`6@3T9H%P#yg^V<7v'
SERVER_PORT: 4000
depends_on:
mysql:
condition: service_healthy
networks:
- nidam-net
token-generator:
build:
context: ./token-generator
dockerfile: Dockerfile
container_name: token-generator
ports:
- "4002:4002"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/identity_hub?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 'CcmN*`6@3T9H%P#yg^V<7v'
SERVER_PORT: 4002
REVERSE_PROXY_URI: http://reverse-proxy:7080
ISSUER: http://reverse-proxy:7080/auth
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:4002/auth/.well-known/openid-configuration" ]
interval: 5s
timeout: 2s
retries: 12
depends_on:
mysql:
condition: service_healthy
networks:
- nidam-net
reverse-proxy:
build:
context: ./reverse-proxy
dockerfile: Dockerfile
container_name: reverse-proxy
ports:
- "7080:7080"
environment:
SERVER_PORT: 7080
REACT_URI: http://nidam-spa:4001/react-ui
AUTHORIZATION_SERVER_URI: http://token-generator:4002/auth
BFF_URI: http://bff:7081
healthcheck:
# test: [ "CMD", "curl", "-f", "http://localhost:7080/actuator/health/readiness" ]
test: [ "CMD", "curl", "-f", "http://localhost:7080/auth/.well-known/openid-configuration" ]
interval: 5s
timeout: 2s
retries: 12
depends_on:
token-generator:
condition: service_healthy
networks:
- nidam-net
nidam:
build:
context: ./nidam
dockerfile: Dockerfile
container_name: nidam
ports:
- "4003:4003"
environment:
SERVER_PORT: 4003
SLEEP_SECONDS: "10"
ISSUER: http://reverse-proxy:7080/auth
REVERSE_PROXY_URI: http://reverse-proxy:7080
depends_on:
reverse-proxy:
condition: service_healthy
networks:
- nidam-net
bff:
build:
context: ./bff
dockerfile: Dockerfile
container_name: bff
ports:
- "7081:7081"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/identity_hub?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 'CcmN*`6@3T9H%P#yg^V<7v'
SERVER_PORT: 7081
# REVERSE_PROXY_URI: http://reverse-proxy:7080
ISSUER: http://reverse-proxy:7080/auth
REACT_URI: http://localhost:7080/react-ui
RESOURCE_SERVER_URI: http://nidam:4003
depends_on:
reverse-proxy:
condition: service_healthy
networks:
- nidam-net
spa:
build:
context: ./nidam-spa
dockerfile: Dockerfile
container_name: nidam-spa
# ports:
# - "4001:4001"
environment:
REACT_APP_BACKEND_REGISTRATION_URL: http://registration:4000/
REACT_APP_REVERSE_PROXY_URI: http://reverse-proxy:7080
REACT_APP_BASE_URI: http://reverse-proxy:7080/react-ui
REACT_APP_RESOURCE_SERVER_URI: http://reverse-proxy:7080/bff/api
REACT_APP_LOGIN_URL: http://reverse-proxy:7080/bff/oauth2/authorization/token-generator
depends_on:
- bff
networks:
- nidam-net
volumes:
mysql_data:
networks:
nidam-net:
driver: bridge
Build & Run
Project Structure
- Create a root directory (e.g.,
Nidam
). - Place all 6 repositories inside this directory.
- Copy the
docker-compose.yml
file into the root directory.
Build & Start
From the terminal, navigate to the root directory and run:
docker compose up --build -d
Once the services are running, open your browser and go to http://localhost:7080/react-ui to access Nidam.