Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Gianluca-X/DigitalMoney/llms.txt
Use this file to discover all available pages before exploring further.
The docker-compose.yml at the root of the repository is the single source of truth for running the entire Digital Money House backend locally. It defines eight services — six Spring Boot microservices built from source, plus MySQL and RabbitMQ pulled from Docker Hub — and wires them together on a shared bridge network with explicit startup dependencies, resource limits, and a MySQL healthcheck that prevents application services from starting before the database is ready.
Services overview
The table below summarises every service defined in docker-compose.yml, including its image or build source, published port, dependencies, and memory limit.
| Service | Image / Build | Host Port → Container Port | Depends On | Memory Limit |
|---|
mysql | mysql:latest | 3308 → 3306 | — | 512m |
eureka-server | Build (./eureka-server/Dockerfile) | 8761 → 8761 | — | 512m |
config-server | Build (./config-server/Dockerfile) | 8888 → 8888 | eureka-server | 512m |
auth-service | Build (./auth-service/Dockerfile) | 8082 → 8082 | mysql (healthy) + eureka-server | 1g |
user-service | Build (./user-service/Dockerfile) | 8087 → 8087 | mysql (healthy) + eureka-server + config-server | 1g |
accounts-service | Build (./accounts-service/Dockerfile) | 8084 → 8084 | mysql (healthy) + eureka-server + config-server | 1g |
gateway | Build (./gateway/Dockerfile) | 8085 → 8085 | eureka-server + config-server | 1g |
rabbitmq | rabbitmq:3-management | 5672 → 5672, 15672 → 15672 | — | 512m |
MySQL is mapped to host port 3308 (not the default 3306) to avoid collisions with a locally installed MySQL instance. Connect your database client to localhost:3308 when inspecting data directly.
Full docker-compose.yml
services:
mysql:
container_name: mysql
mem_limit: 512m
cpus: 0.5
image: mysql:latest
restart: unless-stopped
env_file:
- .env
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${ACCOUNT_DB_DATABASE}
MYSQL_USER: ${ACCOUNT_DB_USERNAME}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3308:3306"
volumes:
- mysql:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- back_network
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root --password=${MYSQL_ROOT_PASSWORD}"]
interval: 30s
retries: 5
timeout: 10s
eureka-server:
container_name: eureka-server
mem_limit: 512m
cpus: 0.5
build:
context: .
dockerfile: ./eureka-server/Dockerfile
ports:
- "8761:8761"
networks:
- back_network
config-server:
container_name: config-server
mem_limit: 512m
cpus: 0.5
build:
context: .
dockerfile: ./config-server/Dockerfile
ports:
- "8888:8888"
env_file:
- .env
environment:
- EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=${EUREKA_CLIENT_SERVICEURL_DEFAULTZONE}
depends_on:
- eureka-server
networks:
- back_network
auth-service:
container_name: auth-service
mem_limit: 1g
cpus: 1
build:
context: .
dockerfile: ./auth-service/Dockerfile
ports:
- "8082:8082"
env_file:
- .env
environment:
- SPRING_DATASOURCE_URL=${AUTH_DB_URL}
- SPRING_DATASOURCE_USERNAME=${AUTH_DB_USERNAME}
- SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD}
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
- SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.MySQLDialect
- JWT_SECRET=${JWT_SECRET}
depends_on:
mysql:
condition: service_healthy
eureka-server:
condition: service_started
networks:
- back_network
user-service:
container_name: user-service
mem_limit: 1g
cpus: 1
build:
context: .
dockerfile: ./user-service/Dockerfile
ports:
- "8087:8087"
env_file:
- .env
environment:
- SPRING_DATASOURCE_URL=${USER_DB_URL}
- SPRING_DATASOURCE_USERNAME=${USER_DB_USERNAME}
- SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD}
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
- SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.MySQLDialect
depends_on:
mysql:
condition: service_healthy
eureka-server:
condition: service_started
config-server:
condition: service_started
networks:
- back_network
accounts-service:
container_name: accounts-service
mem_limit: 1g
cpus: 1
build:
context: .
dockerfile: ./accounts-service/Dockerfile
ports:
- "8084:8084"
env_file:
- .env
environment:
- SPRING_DATASOURCE_URL=${ACCOUNT_DB_URL}
- SPRING_DATASOURCE_USERNAME=${ACCOUNT_DB_USERNAME}
- SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD}
- SPRING_DATASOURCE_DRIVER_CLASS_NAME=com.mysql.cj.jdbc.Driver
- SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.MySQLDialect
- JWT_SECRET=${JWT_SECRET}
depends_on:
mysql:
condition: service_healthy
eureka-server:
condition: service_started
config-server:
condition: service_started
networks:
- back_network
gateway:
container_name: gateway
mem_limit: 1g
cpus: 1
build:
context: .
dockerfile: ./gateway/Dockerfile
ports:
- "8085:8085"
env_file:
- .env
environment:
- EUREKA_CLIENT_SERVICEURL_DEFAULTZONE=${EUREKA_CLIENT_SERVICEURL_DEFAULTZONE}
depends_on:
- eureka-server
- config-server
networks:
- back_network
rabbitmq:
container_name: rabbitmq
mem_limit: 512m
cpus: 0.5
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
networks:
- back_network
volumes:
mysql:
postgres_data:
networks:
back_network:
driver: bridge
MySQL healthcheck
MySQL is the only service configured with a Docker healthcheck. The check runs mysqladmin ping as the root user every 30 seconds with a 10-second timeout and up to 5 retries before the container is marked as unhealthy:
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root --password=${MYSQL_ROOT_PASSWORD}"]
interval: 30s
retries: 5
timeout: 10s
Services that declare condition: service_healthy for MySQL — auth-service, user-service, and accounts-service — will not start until this check passes. This prevents Communications link failure errors caused by a service attempting to open a connection pool before MySQL has finished initialising.
Database initialisation
On the very first run (when the mysql named volume does not yet exist), MySQL automatically executes init.sql from the docker-entrypoint-initdb.d/ directory. This script creates all three service databases and their dedicated users:
-- Create databases
CREATE DATABASE IF NOT EXISTS user_service_db;
CREATE DATABASE IF NOT EXISTS account_service_db;
CREATE DATABASE IF NOT EXISTS auth_service_db;
-- Create per-service users
CREATE USER IF NOT EXISTS 'user_service_user'@'%' IDENTIFIED BY 'nerea';
GRANT ALL PRIVILEGES ON user_service_db.* TO 'user_service_user'@'%';
CREATE USER IF NOT EXISTS 'account_service_user'@'%' IDENTIFIED BY 'nerea';
GRANT ALL PRIVILEGES ON account_service_db.* TO 'account_service_user'@'%';
CREATE USER IF NOT EXISTS 'auth_service_user'@'%' IDENTIFIED BY 'nerea';
GRANT ALL PRIVILEGES ON auth_service_db.* TO 'auth_service_user'@'%';
FLUSH PRIVILEGES;
init.sql only runs when MySQL initialises a fresh data directory. If the mysql volume already exists from a previous run, the script is skipped. To force re-initialisation, remove the volume with docker-compose down -v.
Networks
All eight services are connected to a single bridge network named back_network:
networks:
back_network:
driver: bridge
Docker’s embedded DNS resolves each service by its container name within this network, which is why database URLs and Eureka registration URLs use hostnames like mysql and eureka-server rather than IP addresses.
Volumes
Two named volumes are declared:
| Volume | Used by | Purpose |
|---|
mysql | mysql service | Persists database files across container restarts |
postgres_data | — | Reserved for the PostgreSQL migration branch; unused on main |
The mysql volume is mounted at /var/lib/mysql inside the MySQL container, ensuring that all three service databases survive a docker-compose down (without -v).
Dockerfile pattern
Each microservice has its own Dockerfile located in its subdirectory. All Dockerfiles follow the same single-stage pattern: copy a pre-built JAR from target/ and launch it with the openjdk:21 base image.
FROM openjdk:21
ARG JAR_FILE=<service-name>/target/<service-name>.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
EXPOSE <port>
The build context for every service is the repository root (.), not the service subdirectory. This is required because the JAR_FILE ARG references a path like accounts-service/target/accounts-service.jar — a path that is only valid when the context includes the whole repository.
build:
context: .
dockerfile: ./accounts-service/Dockerfile
Because the build context is the entire repository, the first docker-compose up --build can be slow. Subsequent builds are fast thanks to Docker layer caching — only the layer that copies the JAR is invalidated when you rebuild a service.
The per-service Dockerfile locations and exposed ports are:
| Service | Dockerfile | Exposed Port |
|---|
eureka-server | ./eureka-server/Dockerfile | 8761 |
config-server | ./config-server/Dockerfile | 8888 |
auth-service | ./auth-service/Dockerfile | 8082 |
user-service | ./user-service/Dockerfile | 8087 |
accounts-service | ./accounts-service/Dockerfile | 8084 |
gateway | ./gateway/Dockerfile | 8085 |
Commands cheat sheet
| Goal | Command |
|---|
| Start all services (foreground) | docker-compose up |
| Start all services (detached) | docker-compose up -d |
| Stop and remove containers | docker-compose down |
| Stop, remove containers and volumes | docker-compose down -v |
| Tail logs for one service | docker-compose logs -f <service-name> |
| Rebuild images and restart | docker-compose up --build |
| Restart a single service | docker-compose restart <service-name> |
| View running containers | docker-compose ps |
| Execute a command in a running container | docker-compose exec <service-name> <cmd> |
Running docker-compose down -v deletes the mysql named volume and all stored data. All three service databases will be recreated from init.sql on the next startup, but any application data will be permanently lost.