diff --git a/.dockerignore b/.dockerignore index 28fb10712f..ce7b14d46d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,71 @@ +# Configuration files - exclude potentially sensitive props but allow templates and default configs obp-api/src/main/resources/props/* !obp-api/src/main/resources/props/sample.props.template -!obp-api/src/main/resources/props/test.default.props.template \ No newline at end of file +!obp-api/src/main/resources/props/test.default.props.template +!obp-api/src/main/resources/props/test.default.props +!obp-api/src/main/resources/props/default.props +!obp-api/src/main/resources/props/development.default.props + +# IDE and editor files +.idea/ +.vscode/ +.metals/ +.bloop/ +.run/ +.zed/ +zed/ + +# Build artifacts and caches +target/ +cache/ +~/.m2/ + +# Git and version control +.git/ +.gitignore + +# Environment and secret files +.env +.env.* +*.key +*.pem +*.p12 +*.jks +*secret* +*password* + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Log files +*.log +logs/ + +# Temporary files +*.tmp +*.temp +*.swp +*.swo +*~ + +# Documentation and non-essential files (keep essential ones) +README.md +*.md +!NOTICE +!GNU_AFFERO_GPL_V3_19_Nov_1997.txt +!Harmony_Individual_Contributor_Assignment_Agreement.txt + +# Docker files themselves (avoid recursive copies) +Dockerfile +development/docker/ +!development/docker/entrypoint.sh + +# Test and development files +ideas/ +resourcedoc/ \ No newline at end of file diff --git a/development/docker/.env b/development/docker/.env new file mode 100644 index 0000000000..9f031eb4c3 --- /dev/null +++ b/development/docker/.env @@ -0,0 +1,17 @@ +# Docker Compose Environment Configuration for OBP-API Development + +# Redis Configuration +# Set custom Redis port (externally exposed port) +# The Redis container will be accessible on this port from the host machine +# Default is 6380 to avoid conflicts with local Redis on 6379 +OBP_CACHE_REDIS_PORT=6380 + +# Database Configuration +# Set custom database URL for Docker environment +# Default connects to host PostgreSQL via host.docker.internal +OBP_DB_URL=jdbc:postgresql://host.docker.internal:5432/obp_mapped?user=obp&password=f + +# You can override these by setting environment variables: +# export OBP_CACHE_REDIS_PORT=6381 +# export OBP_DB_URL="jdbc:postgresql://host.docker.internal:5432/mydb?user=myuser&password=mypass" +# docker-compose up --build \ No newline at end of file diff --git a/Dockerfile b/development/docker/Dockerfile similarity index 100% rename from Dockerfile rename to development/docker/Dockerfile diff --git a/development/docker/Dockerfile.dev b/development/docker/Dockerfile.dev new file mode 100644 index 0000000000..d24ca0f644 --- /dev/null +++ b/development/docker/Dockerfile.dev @@ -0,0 +1,28 @@ +FROM maven:3.9.6-eclipse-temurin-17 + +WORKDIR /app + +# Copy Maven configuration files +COPY pom.xml . +COPY build.sbt . + +# Copy source code and necessary project files +COPY obp-api/ ./obp-api/ +COPY obp-commons/ ./obp-commons/ +COPY project/ ./project/ + +# Copy other necessary files for the build +COPY jitpack.yml . +COPY web-app_2_3.dtd . + +EXPOSE 8080 + +# Build the project, skip tests to speed up +RUN mvn install -pl .,obp-commons -am -DskipTests + +# Copy entrypoint script that runs mvn with needed JVM flags +COPY development/docker/entrypoint.sh /app/entrypoint.sh +RUN chmod +x /app/entrypoint.sh + +# Use script as entrypoint +CMD ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/development/docker/README.md b/development/docker/README.md new file mode 100644 index 0000000000..397678231c --- /dev/null +++ b/development/docker/README.md @@ -0,0 +1,241 @@ +# OBP-API Docker Development Setup + +This Docker Compose setup provides a complete **live development environment** for OBP-API with Redis caching support and hot reloading capabilities. + +## Services + +### 🏦 **obp-api-app** +- Main OBP-API application with **live development mode** +- Built with Maven 3.9.6 + OpenJDK 17 +- Runs with Jetty Maven Plugin (`mvn jetty:run`) +- Port: `8080` +- **Features**: Hot reloading, incremental compilation, live props changes + +### πŸ”΄ **obp-api-redis** +- Redis cache server +- Version: Redis 7 Alpine +- Internal port: `6379` +- External port: `6380` (configurable) +- Persistent storage with AOF + +## Quick Start + +1. **Prerequisites** + - Docker and Docker Compose installed + - Local PostgreSQL database running + - Props file configured at `obp-api/src/main/resources/props/default.props` + +2. **Start services** + ```bash + cd development/docker + docker-compose up --build + ``` + +3. **Access application** + - OBP-API: http://localhost:8080 + - Redis: `localhost:6380` + +## Configuration + +### Database Connection + +You can configure the database connection in multiple ways: + +**Option 1: Props file** (traditional): +```properties +db.driver=org.postgresql.Driver +db.url=jdbc:postgresql://host.docker.internal:5432/obp_mapped?user=obp&password=yourpassword +``` + +**Option 2: Environment variables** (recommended for Docker): +The setup automatically overrides database settings via environment variables, so you can configure without modifying props files. + +### Redis Configuration + +Redis is configured automatically using OBP-API's environment variable override system: + +```yaml +# Automatically set by docker-compose.yml: +OBP_CACHE_REDIS_URL=redis # Connect to redis service +OBP_CACHE_REDIS_PORT=6379 # Internal Docker port +OBP_DB_URL=jdbc:postgresql://host.docker.internal:5432/obp_mapped?user=obp&password=f +``` + +### Custom Redis Port + +To customize configuration, edit `.env`: + +```bash +# .env file +OBP_CACHE_REDIS_PORT=6381 +OBP_DB_URL=jdbc:postgresql://host.docker.internal:5432/mydb?user=myuser&password=mypass +``` + +Or set environment variables: + +```bash +export OBP_CACHE_REDIS_PORT=6381 +export OBP_DB_URL="jdbc:postgresql://host.docker.internal:5432/mydb?user=myuser&password=mypass" +docker-compose up --build +``` + +## Container Names + +All containers use consistent `obp-api-*` naming: + +- `obp-api-app` - Main application +- `obp-api-redis` - Redis cache server +- `obp-api-network` - Docker network +- `obp-api-redis-data` - Redis data volume + +## Development Features + +### Props File Override + +The setup mounts your local props directory: +```yaml +volumes: + - ../../obp-api/src/main/resources/props:/app/props +``` + +Environment variables take precedence over props files using OBP's built-in system: +- `cache.redis.url` β†’ `OBP_CACHE_REDIS_URL` +- `cache.redis.port` β†’ `OBP_CACHE_REDIS_PORT` +- `db.url` β†’ `OBP_DB_URL` + +### Live Development Features + +**πŸ”₯ Hot Reloading**: `Dockerfile.dev` uses `mvn jetty:run` for automatic recompilation and reloading: +- βœ… **Scala code changes** - Automatic recompilation and reload +- βœ… **Props file changes** - Live configuration updates via volume mount +- βœ… **Resource changes** - Instant refresh without container restart +- βœ… **Incremental builds** - Only changed files are recompiled + +**Volume Mounts for Development**: +```yaml +# Automatically mounted by docker-compose: +volumes: + - ../../obp-api/src/main/resources/props:/app/props # Live props updates + # Source code is copied during build for optimal performance +``` + +## Useful Commands + +### Service Management +```bash +# Start services +docker-compose up -d + +# View logs +docker-compose logs obp-api-app +docker-compose logs obp-api-redis + +# Stop services +docker-compose down + +# Rebuild and restart +docker-compose up --build +``` + +### Redis Operations +```bash +# Connect to Redis CLI +docker exec -it obp-api-redis redis-cli + +# Check Redis keys +docker exec obp-api-redis redis-cli KEYS "*" + +# Monitor Redis commands +docker exec obp-api-redis redis-cli MONITOR +``` + +### Container Inspection +```bash +# List containers +docker-compose ps + +# Execute commands in containers +docker exec -it obp-api-app bash +docker exec -it obp-api-redis sh +``` + +## Troubleshooting + +### Redis Connection Issues +- Check if `OBP_CACHE_REDIS_URL=redis` is set correctly +- Verify Redis container is running: `docker-compose ps` +- Test Redis connection: `docker exec obp-api-redis redis-cli ping` + +### Database Connection Issues +- Ensure local PostgreSQL is running +- Verify `host.docker.internal` resolves: `docker exec obp-api-app ping host.docker.internal` +- Check props file is mounted: `docker exec obp-api-app ls /app/props/` + +### Props Loading Issues +- Check external props are detected: `docker-compose logs obp-api-app | grep "external props"` +- Verify environment variables: `docker exec obp-api-app env | grep OBP_` + +## Environment Variables + +The setup uses OBP-API's built-in environment override system: + +| Props File Property | Environment Variable | Default | Description | +|---------------------|---------------------|---------|-------------| +| `cache.redis.url` | `OBP_CACHE_REDIS_URL` | `redis` | Redis hostname | +| `cache.redis.port` | `OBP_CACHE_REDIS_PORT` | `6379` | Redis port | +| `cache.redis.password` | `OBP_CACHE_REDIS_PASSWORD` | - | Redis password | +| `db.url` | `OBP_DB_URL` | `jdbc:postgresql://host.docker.internal:5432/obp_mapped?user=obp&password=f` | Database connection URL | + +## Network Architecture + +``` +Host Machine +β”œβ”€β”€ PostgreSQL :5432 +β”œβ”€β”€ Props Files (mounted) β†’ Docker Container +└── Docker Network (obp-api-network) + β”œβ”€β”€ obp-api-app :8080 β†’ :8080 (Live Development Mode) + └── obp-api-redis :6379 β†’ :6380 (Persistent Cache) +``` + +**Connection Flow**: +- OBP-API ↔ Redis: Internal Docker network (`redis:6379`) +- OBP-API ↔ PostgreSQL: Host connection (`host.docker.internal:5432`) +- Props Files: Live mounted from host (`/app/props/`) +- Redis External: Accessible via `localhost:6380` + +## Development Benefits + +### ⚑ **Live Development Mode** (`Dockerfile.dev`) +- **Single-stage build** optimized for development speed +- **Hot reloading** with `mvn jetty:run` - code changes are reflected instantly +- **Incremental compilation** - only changed files are rebuilt +- **Live props updates** - configuration changes without container restart +- **Security compliant** - selective file copying (SonarQube approved) + +### πŸ”§ **Development vs Production** +- **Current setup**: Uses `Dockerfile.dev` for optimal development experience +- **Production ready**: Can switch to `Dockerfile` for multi-stage production builds +- **Best of both**: Live development with production-grade security practices + +### πŸ“‹ **Additional Notes** +- Redis data persists in `obp-api-redis-data` volume +- Props files are live-mounted from host for instant updates +- Environment variables override props file values automatically +- Java 17 with proper module system compatibility +- All containers restart automatically unless stopped manually + +--- + +πŸš€ **Ready for live development!** + +```bash +cd development/docker +docker-compose up --build +# Start coding - changes are reflected automatically! πŸ”₯ +``` + +**Pro Tips**: +- Make code changes and see them instantly without rebuilding +- Update props files and they're loaded immediately +- Use `docker-compose logs obp-api -f` to watch live application logs +- Redis caching speeds up API responses significantly \ No newline at end of file diff --git a/development/docker/docker-compose.override.yml b/development/docker/docker-compose.override.yml new file mode 100644 index 0000000000..5c2291bf36 --- /dev/null +++ b/development/docker/docker-compose.override.yml @@ -0,0 +1,7 @@ +version: "3.8" + +services: + obp-api: + volumes: + - ../../obp-api:/app/obp-api + - ../../obp-commons:/app/obp-commons diff --git a/development/docker/docker-compose.yml b/development/docker/docker-compose.yml new file mode 100644 index 0000000000..5b92c2c693 --- /dev/null +++ b/development/docker/docker-compose.yml @@ -0,0 +1,54 @@ +version: "3.8" + +services: + redis: + container_name: obp-api-redis + image: redis:7-alpine + ports: + - "${OBP_CACHE_REDIS_PORT:-6380}:6379" + command: redis-server --appendonly yes + volumes: + - redis_data:/data + networks: + - obp-network + + obp-api: + container_name: obp-api-app + build: + context: ../.. + dockerfile: development/docker/Dockerfile.dev + ports: + - "8080:8080" + environment: + # Set Lift props location to find your props files + - props.resource.dir=/app/props/ + - JAVA_OPTS=-Drun.mode=production -Dprops.resource.dir=/app/props/ + # Override Redis settings via environment variables (OBP-API system) + # cache.redis.url -> OBP_CACHE_REDIS_URL + # cache.redis.port -> OBP_CACHE_REDIS_PORT + - OBP_CACHE_REDIS_URL=redis + - OBP_CACHE_REDIS_PORT=6379 + # Override database URL via environment variable (OBP-API system) + # db.url -> OBP_DB_URL + - OBP_DB_URL=${OBP_DB_URL:-jdbc:postgresql://host.docker.internal:5432/obp_mapped?user=obp&password=f} + volumes: + # Mount the props directory so the container uses your local props files + - ../../obp-api/src/main/resources/props:/app/props + extra_hosts: + # Connect to local Postgres on the host + # In your config file: + # db.url=jdbc:postgresql://host.docker.internal:5432/YOUR_DB?user=YOUR_DB_USER&password=YOUR_DB_PASSWORD + - "host.docker.internal:host-gateway" + depends_on: + - redis + networks: + - obp-network + +volumes: + redis_data: + name: obp-api-redis-data + +networks: + obp-network: + name: obp-api-network + driver: bridge diff --git a/docker/entrypoint.sh b/development/docker/entrypoint.sh similarity index 100% rename from docker/entrypoint.sh rename to development/docker/entrypoint.sh diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 53a999d1dc..0000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM maven:3.9.6-eclipse-temurin-17 - -WORKDIR /app - -# Copy all project files into container -COPY . . - -EXPOSE 8080 - -# Build the project, skip tests to speed up -RUN mvn install -pl .,obp-commons -am -DskipTests - -# Copy entrypoint script that runs mvn with needed JVM flags -COPY docker/entrypoint.sh /app/entrypoint.sh -RUN chmod +x /app/entrypoint.sh - -# Use script as entrypoint -CMD ["/app/entrypoint.sh"] diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index 1c46f09e0e..0000000000 --- a/docker/README.md +++ /dev/null @@ -1,96 +0,0 @@ -## OBP API – Docker & Docker Compose Setup - -This project uses Docker and Docker Compose to run the **OBP API** service with Maven and Jetty. - -- Java 17 with reflection workaround -- Connects to your local Postgres using `host.docker.internal` -- Supports separate dev & prod setups - ---- - -## How to use - -> **Make sure you have Docker and Docker Compose installed.** - -### Set up the database connection - -Edit your `default.properties` (or similar config file): - -```properties -db.url=jdbc:postgresql://host.docker.internal:5432/YOUR_DB_NAME?user=YOUR_DB_USER&password=YOUR_DB_PASSWORD -```` - -> Use `host.docker.internal` so the container can reach your local database. - ---- - -### Build & run (production mode) - -Build the Docker image and run the container: - -```bash -docker-compose up --build -``` - -The service will be available at [http://localhost:8080](http://localhost:8080). - ---- - -## Development tips - -For live code updates without rebuilding: - -* Use the provided `docker-compose.override.yml` which mounts only: - - ```yaml - volumes: - - ../obp-api:/app/obp-api - - ../obp-commons:/app/obp-commons - ``` -* This keeps other built files (like `entrypoint.sh`) intact. -* Avoid mounting the full `../:/app` because it overwrites the built image. - ---- - -## Useful commands - -Rebuild the image and restart: - -```bash -docker-compose up --build -``` - -Stop the container: - -```bash -docker-compose down -``` - ---- - -## Before first run - -Make sure your entrypoint script is executable: - -```bash -chmod +x docker/entrypoint.sh -``` - ---- - -## Notes - -* The container uses `MAVEN_OPTS` to pass JVM `--add-opens` flags needed by Lift. -* In production, avoid volume mounts for better performance and consistency. - ---- - -That’s it β€” now you can run: - -```bash -docker-compose up --build -``` - -and start coding! - -``` \ No newline at end of file diff --git a/docker/docker-compose.override.yml b/docker/docker-compose.override.yml deleted file mode 100644 index 80e973a2cd..0000000000 --- a/docker/docker-compose.override.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: "3.8" - -services: - obp-api: - volumes: - - ../obp-api:/app/obp-api - - ../obp-commons:/app/obp-commons diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index ca4eda42a0..0000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: "3.8" - -services: - obp-api: - build: - context: .. - dockerfile: docker/Dockerfile - ports: - - "8080:8080" - extra_hosts: - # Connect to local Postgres on the host - # In your config file: - # db.url=jdbc:postgresql://host.docker.internal:5432/YOUR_DB?user=YOUR_DB_USER&password=YOUR_DB_PASSWORD - - "host.docker.internal:host-gateway"