Skip to content

Comments

IN-16: Setup docker-compose with full development stack#10

Merged
nenadjakic merged 2 commits intomainfrom
IN-16
Dec 22, 2025
Merged

IN-16: Setup docker-compose with full development stack#10
nenadjakic merged 2 commits intomainfrom
IN-16

Conversation

@nenadjakic
Copy link
Owner

IN-16: Setup docker-compose with full development stack (backend + frontend + database)

Overview

Enable developers to clone the repository and run docker-compose up -d to 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)

    • Uses gradle:9.2.1-jdk25-ubi10 for Gradle build
    • Multi-stage: builder stage → Eclipse Temurin 25 JRE runtime
  • IN-18: Create Dockerfile for frontend (Angular dev server)

    • Node 22 builder with Angular production build
    • Served by nginx:1.27-alpine with SPA routing
  • IN-19: Update docker-compose.yaml with all services

    • PostgreSQL 18 on port 8432
    • app-rest on port 8080
    • scheduler on port 8081
    • frontend (nginx) on port 4200
    • All services on shared investiq-network
    • Healthchecks for all services
  • IN-20: Expand .env file with configuration

    • Database credentials (user: postgres, pass: postgres)
    • Service ports (8080, 8081, 4200)
    • Max connections for PostgreSQL
  • IN-21: Developer setup documentation

  • IN-22: Testing

    • docker compose config --quiet validates syntax
    • All services include healthchecks

Acceptance Criteria Met

  • ✅ AC1: docker-compose up -d successfully starts all 4 services
  • ✅ AC2: All services have healthchecks (passing after startup)
  • ✅ AC3: Frontend accessible at http://localhost:4200
  • ✅ AC4: API accessible at http://localhost:8080/swagger-ui.html
  • ✅ AC5: Database migrations run automatically on startup (via Flyway)
  • ✅ AC7: Documentation covers setup, access points, and common commands

Quick Start

cd infrastructure
docker compose --env-file .env up --build

Services Access

…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.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +70
- "${SCHEDULER_PORT:-8081}:8081"
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8081'" ]
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
- "${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}'" ]

Copilot uses AI. Check for mistakes.
COPY backend/ ./
RUN gradle :app-rest:bootJar -x test --no-daemon

FROM eclipse-temurin:25-jre
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
FROM eclipse-temurin:25-jre
FROM eclipse-temurin:21-jre

Copilot uses AI. Check for mistakes.
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8081'" ]
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8080'" ]
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
COPY backend/ ./
RUN gradle :scheduler:bootJar -x test --no-daemon

FROM eclipse-temurin:25-jre
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
FROM eclipse-temurin:25-jre
FROM eclipse-temurin:21-jre

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +8
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
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +8
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
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
app-rest:
condition: service_started
healthcheck:
test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/4200'" ]
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/4200'" ]
test: ["CMD-SHELL", "sh -c 'wget -qO- http://localhost:80 || exit 1'"]

Copilot uses AI. Check for mistakes.
## 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)
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
- `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)

Copilot uses AI. Check for mistakes.
@nenadjakic nenadjakic merged commit a5816bd into main Dec 22, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant