IN-16: Setup docker-compose with full development stack#10
Conversation
…ontend + database) - Create Dockerfile for backend (app-rest + scheduler) with gradle:9.2.1-jdk25-ubi10 builder - Create Dockerfile for frontend (Angular) with Node 22 builder and nginx runtime - Update docker-compose.yaml with app-rest, scheduler, frontend, and PostgreSQL services - Expand .env file with service configuration variables (ports, DB credentials) - Create/update developer setup documentation for Docker environment - Enable Spring Boot DevTools for hot reload in app-rest and scheduler - Update Gradle wrapper to 9.10 and use JDK 25 All services include healthchecks and proper networking. Build context uses repo root for access to all source directories.
There was a problem hiding this comment.
Pull request overview
This PR establishes a complete Docker Compose development environment for InvestIQ, enabling developers to launch the full stack (PostgreSQL, REST API, scheduler, and Angular frontend) with a single command. The implementation uses multi-stage Docker builds for both backend services and the frontend, with comprehensive health checks and service dependencies configured.
Key Changes:
- Multi-stage Dockerfiles for backend services (Gradle build → JRE runtime) and frontend (Node.js build → nginx)
- Docker Compose configuration with 4 services (postgres, app-rest, scheduler, frontend) on a shared network
- Environment-based configuration via .env file with all service ports and database credentials
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| infrastructure/docker-compose.yaml | Defines all 4 services with health checks, dependencies, and networking; added postgres healthcheck and 3 new services |
| infrastructure/.env | Added service port configurations (8080, 8081, 4200) to existing database settings |
| infrastructure/README.md | New comprehensive documentation covering setup, services, and common Docker commands |
| infrastructure/frontend/Dockerfile | Multi-stage build: Node 22 for Angular production build, nginx for serving static assets |
| infrastructure/frontend/nginx.conf | Nginx configuration with SPA routing support and asset caching headers |
| infrastructure/backend/Dockerfile.app-rest | Multi-stage build: Gradle builder with JDK 25, Eclipse Temurin JRE runtime |
| infrastructure/backend/Dockerfile.scheduler | Multi-stage build: Gradle builder with JDK 25, Eclipse Temurin JRE runtime |
| backend/app-rest/build.gradle.kts | Added developmentOnly configuration and spring-boot-devtools dependency |
| backend/scheduler/build.gradle.kts | Added developmentOnly configuration and spring-boot-devtools dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,47 @@ | |||
| # InvestIQ Docker Compose | |||
|
|
|||
| Production stack that builds runnable JAR files for app-rest (8080) and scheduler (8081) with nginx-served Angular build (4200). PostgreSQL 18 on port 8432. Jedan compose, jedan .env. | |||
There was a problem hiding this comment.
There's a typo in the documentation: "Jedan compose, jedan .env" appears to be in Serbian/Croatian. This should be in English to maintain consistency with the rest of the documentation.
| Production stack that builds runnable JAR files for app-rest (8080) and scheduler (8081) with nginx-served Angular build (4200). PostgreSQL 18 on port 8432. Jedan compose, jedan .env. | |
| Production stack that builds runnable JAR files for app-rest (8080) and scheduler (8081) with nginx-served Angular build (4200). PostgreSQL 18 on port 8432. Single compose file, single `.env` file. |
| - "${SCHEDULER_PORT:-8081}:8081" | ||
| depends_on: | ||
| postgres: | ||
| condition: service_healthy | ||
| healthcheck: | ||
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8081'" ] |
There was a problem hiding this comment.
The scheduler's SERVER_PORT environment variable is set to use the SCHEDULER_PORT value (defaulting to 8081), but the port mapping on line 65 maps the same SCHEDULER_PORT to container port 8081. This creates a potential mismatch if SCHEDULER_PORT is changed in .env to something other than 8081, as the container will listen on one port but the mapping expects 8081. The port mapping should consistently use ${SCHEDULER_PORT:-8081}:${SCHEDULER_PORT:-8081} or the SERVER_PORT should be hardcoded to 8081.
| - "${SCHEDULER_PORT:-8081}:8081" | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8081'" ] | |
| - "${SCHEDULER_PORT:-8081}:${SCHEDULER_PORT:-8081}" | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/${SCHEDULER_PORT:-8081}'" ] |
| COPY backend/ ./ | ||
| RUN gradle :app-rest:bootJar -x test --no-daemon | ||
|
|
||
| FROM eclipse-temurin:25-jre |
There was a problem hiding this comment.
The image tag 'eclipse-temurin:25-jre' references Java 25, which may not be a stable LTS release. Eclipse Temurin typically provides LTS versions (8, 11, 17, 21). Using a non-LTS or pre-release version in production could lead to stability and support issues. Consider using a stable LTS version like eclipse-temurin:21-jre.
| FROM eclipse-temurin:25-jre | |
| FROM eclipse-temurin:21-jre |
| postgres: | ||
| condition: service_healthy | ||
| healthcheck: | ||
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8081'" ] |
There was a problem hiding this comment.
The UBI (Universal Base Image) used in the builder stage may not have bash available in the final Eclipse Temurin JRE image. The healthcheck should use 'sh -c' instead of 'bash -c' for better portability, or consider using a more robust healthcheck method like curl/wget if available.
| postgres: | ||
| condition: service_healthy | ||
| healthcheck: | ||
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8080'" ] |
There was a problem hiding this comment.
The UBI (Universal Base Image) used in the builder stage may not have bash available in the final Eclipse Temurin JRE image. The healthcheck should use 'sh -c' instead of 'bash -c' for better portability, or consider using a more robust healthcheck method like curl/wget if available.
| COPY backend/ ./ | ||
| RUN gradle :scheduler:bootJar -x test --no-daemon | ||
|
|
||
| FROM eclipse-temurin:25-jre |
There was a problem hiding this comment.
The image tag 'eclipse-temurin:25-jre' references Java 25, which may not be a stable LTS release. Eclipse Temurin typically provides LTS versions (8, 11, 17, 21). Using a non-LTS or pre-release version in production could lead to stability and support issues. Consider using a stable LTS version like eclipse-temurin:21-jre.
| FROM eclipse-temurin:25-jre | |
| FROM eclipse-temurin:21-jre |
| FROM gradle:9.2.1-jdk25-ubi10 AS builder | ||
|
|
||
| WORKDIR /workspace | ||
| COPY backend/ ./ | ||
| RUN gradle :app-rest:bootJar -x test --no-daemon | ||
|
|
||
| FROM eclipse-temurin:25-jre |
There was a problem hiding this comment.
The image tag 'gradle:9.2.1-jdk25-ubi10' uses JDK 25, which may not be a stable LTS release. This is inconsistent with best practices for production builds and could lead to compatibility issues. Consider using a Gradle image with a stable LTS JDK version like jdk21 to match the Eclipse Temurin LTS versions.
| FROM gradle:9.2.1-jdk25-ubi10 AS builder | |
| WORKDIR /workspace | |
| COPY backend/ ./ | |
| RUN gradle :app-rest:bootJar -x test --no-daemon | |
| FROM eclipse-temurin:25-jre | |
| FROM gradle:9.2.1-jdk21-ubi10 AS builder | |
| WORKDIR /workspace | |
| COPY backend/ ./ | |
| RUN gradle :app-rest:bootJar -x test --no-daemon | |
| FROM eclipse-temurin:21-jre |
| FROM gradle:9.2.1-jdk25-ubi10 AS builder | ||
|
|
||
| WORKDIR /workspace | ||
| COPY backend/ ./ | ||
| RUN gradle :scheduler:bootJar -x test --no-daemon | ||
|
|
||
| FROM eclipse-temurin:25-jre |
There was a problem hiding this comment.
The image tag 'gradle:9.2.1-jdk25-ubi10' uses JDK 25, which may not be a stable LTS release. This is inconsistent with best practices for production builds and could lead to compatibility issues. Consider using a Gradle image with a stable LTS JDK version like jdk21 to match the Eclipse Temurin LTS versions.
| FROM gradle:9.2.1-jdk25-ubi10 AS builder | |
| WORKDIR /workspace | |
| COPY backend/ ./ | |
| RUN gradle :scheduler:bootJar -x test --no-daemon | |
| FROM eclipse-temurin:25-jre | |
| FROM gradle:9.2.1-jdk21-ubi10 AS builder | |
| WORKDIR /workspace | |
| COPY backend/ ./ | |
| RUN gradle :scheduler:bootJar -x test --no-daemon | |
| FROM eclipse-temurin:21-jre |
| app-rest: | ||
| condition: service_started | ||
| healthcheck: | ||
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/4200'" ] |
There was a problem hiding this comment.
The frontend healthcheck has two issues: (1) it's testing port 4200, but nginx listens on port 80 inside the container (see EXPOSE 80 in Dockerfile line 14), so it should test port 80; (2) Alpine-based nginx images typically don't include bash, so 'bash -c' will fail - use 'sh -c' instead or a simpler command like wget/curl.
| test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/4200'" ] | |
| test: ["CMD-SHELL", "sh -c 'wget -qO- http://localhost:80 || exit 1'"] |
| ## Dockerfiles | ||
| - `infrastructure/backend/Dockerfile.app-rest` — Gradle build (gradle:9.2.1-jdk25-ubi10) → Eclipse Temurin 25 JRE | ||
| - `infrastructure/backend/Dockerfile.scheduler` — Gradle build (gradle:9.2.1-jdk25-ubi10) → Eclipse Temurin 25 JRE | ||
| - `infrastructure/frontend/Dockerfile` — Node.js 22 build → nginx:1.27-alpine (SPA routing, asset caching) |
There was a problem hiding this comment.
The documentation states nginx:1.27-alpine is used, but the actual Dockerfile specifies nginx:1.29.4-alpine. These should be consistent. Additionally, version 1.29.4 does not appear to be a valid nginx version.
| - `infrastructure/frontend/Dockerfile` — Node.js 22 build → nginx:1.27-alpine (SPA routing, asset caching) | |
| - `infrastructure/frontend/Dockerfile` — Node.js 22 build → nginx (Alpine-based image, SPA routing, asset caching) |
IN-16: Setup docker-compose with full development stack (backend + frontend + database)
Overview
Enable developers to clone the repository and run
docker-compose up -dto have a fully functional development environment with PostgreSQL, REST API, scheduler, and Angular frontend all running.Changes
IN-17: Create Dockerfile for backend (app-rest + scheduler)
gradle:9.2.1-jdk25-ubi10for Gradle buildIN-18: Create Dockerfile for frontend (Angular dev server)
IN-19: Update docker-compose.yaml with all services
investiq-networkIN-20: Expand .env file with configuration
IN-21: Developer setup documentation
IN-22: Testing
docker compose config --quietvalidates syntaxAcceptance Criteria Met
docker-compose up -dsuccessfully starts all 4 servicesQuick Start
cd infrastructure docker compose --env-file .env up --buildServices Access