diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 0000000..eb8bf6f --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,59 @@ +# Production Dockerfile for Abada Engine +# This uses a multi-stage build for optimized production images + +# Stage 1: Build with Maven +FROM maven:3.9.6-eclipse-temurin-21 AS builder + +WORKDIR /app + +# Copy only pom.xml first to leverage Docker layer caching for dependencies +COPY pom.xml . +COPY .mvn .mvn +COPY mvnw . + +# Download dependencies (this layer will be cached unless pom.xml changes) +RUN ./mvnw dependency:go-offline -B + +# Copy source code +COPY src ./src + +# Build the application +RUN ./mvnw clean package spring-boot:repackage -DskipTests + +# Stage 2: Runtime +FROM eclipse-temurin:21-jre-alpine + +WORKDIR /app + +# Install su-exec for user switching +RUN apk add --no-cache su-exec + +# Create a non-root user and group for security +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + +# Copy the fat JAR from the builder stage +COPY --from=builder /app/target/abada-engine-*.jar app.jar + +# Copy entrypoint script +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +# Create logs directory and log file +RUN mkdir -p /app/logs && \ + touch /app/logs/abada-engine.logs && \ + chown -R appuser:appgroup /app/logs + +# Create data directory for dev profile +RUN mkdir -p /app/data && \ + chown -R appuser:appgroup /app/data + +# Change ownership to the new user +RUN chown appuser:appgroup app.jar + +# Note: We stay as root so entrypoint can fix volume permissions +# The entrypoint script will switch to appuser before running the app + +EXPOSE 5601 + +# Run the application via entrypoint script +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh", "java", "-jar", "app.jar"] diff --git a/README.md b/README.md index c4bdeb1..174e03d 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,51 @@ All components are containerized and deploy independently. For design, boundarie --- -## Quick Start (Docker) +## Quick Start -Get up and running in minutes with our curated Compose stacks: +## Quick Start -- **Development**: Hot-reloading and debug ports exposed. -- **Production**: Optimized, secure, and scalable. +### 🚀 Launch Platform (Production/Demo) -See [`docs/docker-deployment.md`](docs/docker-deployment.md) for commands and [`docs/docker-deployment-plan.md`](docs/docker-deployment-plan.md) for the environment strategy. +The easiest way to run the full Abada Platform (Engine, Tenda, Orun, Observability) is using our automated quickstart script. You only need Docker installed. + +```bash +curl -sSL https://raw.githubusercontent.com/bashizip/abada-engine/main/release/quickstart.sh | bash +``` + +### 💻 Development Environment + +For developers contributing to the project: + +Hosted with in-memory H2 database, pre-configured users, and full observability tools. + +**Option 1: Build & Run (Recommended)** +Builds the engine locally (fast) and launches the **complete** stack. +```bash +./scripts/build-and-run-dev.sh +``` + +**Option 2: Start Only** +Starts the containers if the image is already built. +```bash +./scripts/start-dev.sh +``` + +**Option 3: Rebuild Engine Only (Fast Iteration)** +Rebuilds and restarts only the engine service to apply code changes. +```bash +./scripts/build-dev.sh +``` + +**Services:** +- **Abada Engine**: [http://localhost:5601/abada/api](http://localhost:5601/abada/api) +- **Abada Tenda** (Task UI): [http://localhost:5602](http://localhost:5602) +- **Abada Orun** (Monitoring UI): [http://localhost:5603](http://localhost:5603) +- **Grafana**: [http://localhost:3000](http://localhost:3000) (admin/admin123) +- **Jaeger**: [http://localhost:16686](http://localhost:16686) +- **Traefik Dashboard**: [http://localhost:8080](http://localhost:8080) + +For production deployment and manual Docker Compose commands, see the detailed [Docker Deployment Guide](docs/operations/docker-deployment.md). --- diff --git a/docker-compose.hub.yml b/docker-compose.hub.yml new file mode 100644 index 0000000..353e68b --- /dev/null +++ b/docker-compose.hub.yml @@ -0,0 +1,48 @@ +version: '3.8' + +services: + # Abada Engine - Usage from Docker Hub + abada-engine: + # Use image from Docker Hub instead of local build + image: ${DOCKER_USERNAME:-bashizip}/abada-engine:${VERSION:-latest} + build: + context: . + dockerfile: Dockerfile.prod # Point to prod dockerfile just in case build is forced, but image takes precedence + pull_policy: always + restart: always + + # Abada Tenda - Frontend + abada-tenda: + image: ${DOCKER_USERNAME:-bashizip}/abada-tenda:${VERSION:-latest} + container_name: abada-tenda-prod + ports: + - "5602:5602" + environment: + - NODE_ENV=production + networks: + - abada-network + restart: always + pull_policy: always + healthcheck: + test: [ "CMD", "wget", "--spider", "-q", "http://localhost:5602/health" ] + interval: 30s + timeout: 10s + retries: 3 + + # Abada Orun - Frontend + abada-orun: + image: ${DOCKER_USERNAME:-bashizip}/abada-orun:${VERSION:-latest} + container_name: abada-orun-prod + ports: + - "5603:5603" + environment: + - NODE_ENV=production + networks: + - abada-network + restart: always + pull_policy: always + healthcheck: + test: [ "CMD", "wget", "--spider", "-q", "http://localhost:5603/health" ] + interval: 30s + timeout: 10s + retries: 3 diff --git a/docs/operations/docker-deployment.md b/docs/operations/docker-deployment.md index 2524998..6232c69 100755 --- a/docs/operations/docker-deployment.md +++ b/docs/operations/docker-deployment.md @@ -39,6 +39,41 @@ GRAFANA_ADMIN_PASSWORD=admin123 POSTGRES_PASSWORD=secure_password ``` +## Building Local Images + +You can build the Docker image locally for either production or development. + +### Production Build + +The standard build is a multi-stage process that compiles the code inside the container. This ensures a consistent build environment but takes longer. + +```bash +docker build -t abada-engine:latest . +``` + +### Development Build (Fast) + +For faster iteration, you can build the JAR locally and inject it into the image. This skips the dependency download and build steps inside Docker. + +1. Build the JAR file locally: + + ```bash + ./mvnw clean package -DskipTests + ``` + +2. Build the Docker image using the local JAR: + + ```bash + docker build --build-arg USE_LOCAL_JAR=true -t abada-engine:dev . + ``` + +> [!TIP] +> **Helper Scripts available!** +> You can automate this process using the scripts in the `scripts/` directory: +> - `scripts/build-and-run-dev.sh`: Builds JAR, builds image, and starts full stack. +> - `scripts/build-dev.sh`: Rebuilds engine only (useful for iteration). + + ## Deployment Commands ### Development Environment @@ -46,7 +81,7 @@ POSTGRES_PASSWORD=secure_password Single instance with H2 database, full observability, debug logging: ```bash -docker-compose -f docker-compose.yml -f docker-compose.dev.yml up +docker compose -f docker-compose.yml -f docker-compose.dev.yml up ``` **Access URLs:** @@ -101,6 +136,41 @@ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --scale ab docker-compose -f docker-compose.yml -f docker-compose.prod.yml ps ``` +## Quick Start (Recommended) + +The easiest way to run the platform is using the automated quickstart script. + +### 1. Download and Run +You only need `docker` and `docker compose` installed. + +```bash +# Download and run the quickstart script +curl -sSL https://raw.githubusercontent.com/bashizip/abada-engine/main/release/quickstart.sh | bash +``` + +This script will: +1. Download the production configuration. +2. Start all services using `docker compose`. +3. Show you the access URLs. + +### 2. Manual Setup (Alternative) + +If you prefer to start it manually: + +1. Download the [release configuration](https://raw.githubusercontent.com/bashizip/abada-engine/main/release/docker-compose.release.yml) to a file named `docker-compose.yml`. +2. Run: + ```bash + docker compose up -d + ``` + +### Access URLs + +- **Abada Engine**: (via Traefik) +- **Abada Tenda**: +- **Abada Orun**: +- **Grafana**: +- **Traefik Dashboard**: + ## Monitoring and Observability ### Metrics Flow diff --git a/release/docker-compose.release.yml b/release/docker-compose.release.yml new file mode 100644 index 0000000..d51f05f --- /dev/null +++ b/release/docker-compose.release.yml @@ -0,0 +1,420 @@ +name: abada-engine +services: + abada-engine: + build: + context: /Users/pbash/repo/abada-platform/abada-engine + dockerfile: Dockerfile.prod + depends_on: + otel-collector: + condition: service_started + required: true + postgres: + condition: service_healthy + required: true + deploy: + replicas: 3 + resources: + limits: + cpus: 1 + memory: "1073741824" + reservations: + cpus: 0.5 + memory: "536870912" + environment: + MANAGEMENT_OTLP_METRICS_ENDPOINT: http://otel-collector:4318/v1/metrics + MANAGEMENT_OTLP_TRACING_ENDPOINT: http://otel-collector:4318/v1/traces + MANAGEMENT_TRACING_SAMPLING_PROBABILITY: "0.1" + OTEL_RESOURCE_ATTRIBUTES: project=abada,service.version=0.8.3-alpha + OTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_ENVIRONMENT: prod + OTEL_SERVICE_NAME: abada-engine-prod + SERVER_PORT: "5601" + SPRING_DATASOURCE_PASSWORD: postgres_secure_password + SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/abada_engine + SPRING_DATASOURCE_USERNAME: abada + SPRING_JPA_DATABASE_PLATFORM: org.hibernate.dialect.PostgreSQLDialect + SPRING_JPA_HIBERNATE_DDL_AUTO: update + SPRING_PROFILES_ACTIVE: prod + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:5601/abada/api/actuator/health + timeout: 10s + interval: 30s + retries: 3 + image: bashizip/abada-engine:latest + labels: + traefik.enable: "true" + traefik.http.routers.abada.rule: PathPrefix(`/abada`) + traefik.http.services.abada.loadbalancer.healthcheck.interval: 30s + traefik.http.services.abada.loadbalancer.healthcheck.path: /abada/api/actuator/health + traefik.http.services.abada.loadbalancer.server.port: "5601" + networks: + abada-network: null + pull_policy: always + restart: always + abada-orun: + container_name: abada-orun-prod + environment: + NODE_ENV: production + healthcheck: + test: + - CMD + - wget + - --spider + - -q + - http://localhost:5603/health + timeout: 10s + interval: 30s + retries: 3 + image: bashizip/abada-orun:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 5603 + published: "5603" + protocol: tcp + pull_policy: always + restart: always + abada-tenda: + container_name: abada-tenda-prod + environment: + NODE_ENV: production + healthcheck: + test: + - CMD + - wget + - --spider + - -q + - http://localhost:5602/health + timeout: 10s + interval: 30s + retries: 3 + image: bashizip/abada-tenda:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 5602 + published: "5602" + protocol: tcp + pull_policy: always + restart: always + consul: + container_name: consul + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:8500/v1/status/leader + timeout: 10s + interval: 30s + retries: 3 + image: hashicorp/consul:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 8500 + published: "8500" + protocol: tcp + restart: unless-stopped + grafana: + container_name: grafana + environment: + GF_SECURITY_ADMIN_PASSWORD: admin + GF_USERS_ALLOW_SIGN_UP: "false" + healthcheck: + test: + - CMD-SHELL + - wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1 + timeout: 10s + interval: 30s + retries: 3 + image: grafana/grafana:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 3000 + published: "3000" + protocol: tcp + restart: unless-stopped + volumes: + - type: volume + source: grafana_data + target: /var/lib/grafana + volume: {} + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/grafana/provisioning + target: /etc/grafana/provisioning + read_only: true + bind: + selinux: z + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/grafana/dashboards + target: /var/lib/grafana/dashboards + read_only: true + bind: + selinux: z + jaeger: + container_name: jaeger + environment: + COLLECTOR_OTLP_ENABLED: "true" + JAEGER_STORAGE_TYPE: memory + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:16686/ + timeout: 10s + interval: 30s + retries: 3 + image: jaegertracing/all-in-one:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 16686 + published: "16686" + protocol: tcp + - mode: ingress + target: 14250 + published: "14250" + protocol: tcp + restart: unless-stopped + loki: + command: + - -config.file=/etc/loki/local-config.yaml + - -config.expand-env=true + container_name: loki + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:3100/ready + timeout: 10s + interval: 30s + retries: 3 + image: grafana/loki:2.9.1 + networks: + abada-network: null + ports: + - mode: ingress + target: 3100 + published: "3100" + protocol: tcp + restart: unless-stopped + user: "0:0" + volumes: + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/loki-config-prod.yaml + target: /etc/loki/local-config.yaml + read_only: true + bind: + selinux: z + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/loki-wal + target: /tmp/loki/wal + bind: {} + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/loki-compactor + target: /loki/compactor + bind: {} + otel-collector: + command: + - --config=/etc/otel-collector-config.yaml + container_name: otel-collector + image: otel/opentelemetry-collector-contrib:latest + networks: + abada-network: + aliases: + - otel-collector + ports: + - mode: ingress + target: 4317 + published: "4317" + protocol: tcp + - mode: ingress + target: 4318 + published: "4318" + protocol: tcp + - mode: ingress + target: 8889 + published: "8889" + protocol: tcp + restart: unless-stopped + volumes: + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/otel-collector-config.yaml + target: /etc/otel-collector-config.yaml + read_only: true + bind: + selinux: z + postgres: + container_name: postgres-prod + environment: + POSTGRES_DB: abada_engine + POSTGRES_PASSWORD: postgres_secure_password + POSTGRES_USER: abada + healthcheck: + test: + - CMD-SHELL + - pg_isready -U abada -d abada_engine + timeout: 10s + interval: 30s + retries: 3 + image: postgres:15-alpine + networks: + abada-network: null + ports: + - mode: ingress + target: 5432 + published: "5432" + protocol: tcp + restart: always + volumes: + - type: volume + source: postgres_data + target: /var/lib/postgresql/data + volume: {} + prometheus: + command: + - --config.file=/etc/prometheus/prometheus.yml + - --storage.tsdb.path=/prometheus + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + - --storage.tsdb.retention.time=15d + - --web.enable-lifecycle + container_name: prometheus + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:9090/-/healthy + timeout: 10s + interval: 30s + retries: 3 + image: prom/prometheus:latest + networks: + abada-network: null + ports: + - mode: ingress + target: 9090 + published: "9090" + protocol: tcp + restart: unless-stopped + volumes: + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/prometheus.yml + target: /etc/prometheus/prometheus.yml + read_only: true + bind: + selinux: z + - type: volume + source: prometheus_data + target: /prometheus + volume: {} + promtail: + command: + - -config.file=/etc/promtail/config.yml + container_name: promtail + depends_on: + loki: + condition: service_healthy + required: true + image: grafana/promtail:2.9.1 + networks: + abada-network: null + restart: unless-stopped + volumes: + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/promtail-config.yaml + target: /etc/promtail/config.yml + read_only: true + bind: + selinux: z + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/logs + target: /var/log/abada + read_only: true + bind: + selinux: z + traefik: + command: + - --api.dashboard=true + - --api.insecure=true + - --providers.docker=true + - --providers.docker.exposedbydefault=false + - --entrypoints.web.address=:80 + - --entrypoints.websecure.address=:443 + - --log.level=INFO + - --accesslog=true + container_name: traefik + healthcheck: + test: + - CMD + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:8080/ping + timeout: 10s + interval: 30s + retries: 3 + image: traefik:v3.0 + networks: + abada-network: null + ports: + - mode: ingress + target: 80 + published: "80" + protocol: tcp + - mode: ingress + target: 443 + published: "443" + protocol: tcp + - mode: ingress + target: 8080 + published: "8080" + protocol: tcp + restart: unless-stopped + volumes: + - type: bind + source: /var/run/docker.sock + target: /var/run/docker.sock + read_only: true + bind: {} + - type: bind + source: /Users/pbash/repo/abada-platform/abada-engine/docker/traefik/traefik.yml + target: /etc/traefik/traefik.yml + read_only: true + bind: + selinux: z +networks: + abada-network: + name: abada-engine_abada-network + driver: bridge +volumes: + grafana_data: + name: abada-engine_grafana_data + postgres_data: + name: abada-engine_postgres_data + prometheus_data: + name: abada-engine_prometheus_data diff --git a/release/quickstart.sh b/release/quickstart.sh new file mode 100755 index 0000000..ca3029a --- /dev/null +++ b/release/quickstart.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Abada Platform Quickstart Script +# Downloads and starts the Abada Platform + +set -e + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Configuration +RELEASE_URL="https://raw.githubusercontent.com/bashizip/abada-engine/main/release/docker-compose.release.yml" +LocalFile="docker-compose.release.yml" + +print_header() { + echo -e "${BLUE}" + echo " _ _ _ " + echo " / \ | |__ __ _ __| | __ _ " + echo " / _ \ | '_ \ / _\` |/ _\` |/ _\` | " + echo " / ___ \| |_) | (_| | (_| | (_| | " + echo "/_/ \_\_.__/ \__,_|\__,_|\__,_| " + echo " " + echo " Quickstart Launcher " + echo -e "${NC}" +} + +print_step() { + echo -e "${GREEN}==>${NC} $1" +} + +check_prerequisites() { + print_step "Checking prerequisites..." + if ! command -v docker &> /dev/null; then + echo -e "${RED}Error: docker is not installed.${NC}" + echo "Please install Docker Desktop from https://www.docker.com/products/docker-desktop" + exit 1 + fi + + # Check for docker compose (v2) + if ! docker compose version &> /dev/null; then + echo -e "${RED}Error: docker compose (v2) is not available.${NC}" + echo "Please make sure you have a recent version of Docker Desktop installed." + exit 1 + fi + echo "✓ Docker and Docker Compose found" +} + +download_compose() { + if [ -f "$LocalFile" ]; then + print_step "Using existing $LocalFile" + else + print_step "Downloading configuration..." + if command -v curl &> /dev/null; then + curl -sSL "$RELEASE_URL" -o "$LocalFile" + elif command -v wget &> /dev/null; then + wget -q "$RELEASE_URL" -O "$LocalFile" + else + echo -e "${RED}Error: curl or wget is required to download the configuration.${NC}" + exit 1 + fi + echo "✓ Configuration downloaded" + fi +} + +start_platform() { + print_step "Starting Abada Platform..." + docker compose -f "$LocalFile" up -d + + if [ $? -eq 0 ]; then + echo "" + print_step "Platform available at:" + echo -e " - ${BLUE}Engine ${NC}: http://localhost/abada/api" + echo -e " - ${BLUE}Tenda ${NC}: http://localhost:5602" + echo -e " - ${BLUE}Orun ${NC}: http://localhost:5603" + echo -e " - ${BLUE}Grafana ${NC}: http://localhost:3000" + echo "" + echo "Run 'docker compose -f $LocalFile down' to stop." + else + echo -e "${RED}Error: Failed to start platform.${NC}" + exit 1 + fi +} + +# Main execution +print_header +check_prerequisites +download_compose +start_platform diff --git a/scripts/README.md b/scripts/README.md index 8b4ed1c..514e004 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -60,6 +60,31 @@ Builds a **self-contained production image** from source. ./scripts/prod-build.sh --build-only ``` +### `push-to-dockerhub.sh` + +Builds production-ready images (using `Dockerfile.prod` files) and pushes them to Docker Hub. + +**Usage:** + +```bash +# Push to default user (bashizip) as latest +./scripts/push-to-dockerhub.sh + +# Push to custom user with custom version +export DOCKER_USERNAME=myorg +export VERSION=v1.0.0 +./scripts/push-to-dockerhub.sh +``` + +**Prerequisites:** +- You must be logged in to Docker Hub (`docker login`) +- You must have permissions to push to the target repositories + +**What it does:** +1. Builds production images for Engine, Tenda, and Orun +2. Pushes them to Docker Hub with `${VERSION}` and `:latest` tags + + **What it does:** 1. Builds Docker image from source (Maven runs inside Docker) @@ -125,7 +150,7 @@ Generates sample process instances to preload the engine with test data. See [docs/sample-data-generator.md](../docs/sample-data-generator.md) for detailed documentation. --- - +docke ## Docker Build Architecture The single `Dockerfile` supports both dev and prod builds via the `USE_LOCAL_JAR` build argument. diff --git a/scripts/build-and-run-dev.sh b/scripts/build-and-run-dev.sh new file mode 100755 index 0000000..df885ab --- /dev/null +++ b/scripts/build-and-run-dev.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Helper script for building and running the FULL dev environment (Engine + Observability + DB) + +set -e + +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${BLUE}=== Abada Engine Full Stack Build & Run ===${NC}\n" + +# Check for Java/Maven +if ! command -v java &> /dev/null; then + echo -e "${YELLOW}Warning: Java not found. Local build will likely fail.${NC}" + echo -e "${YELLOW}Ensure you have Java 21+ installed to use the fast local build.${NC}\n" +fi + +# Build the jar locally for faster Docker builds +echo -e "${YELLOW}Step 1: Building JAR locally...${NC}" +./mvnw clean package spring-boot:repackage -DskipTests + +echo -e "\n${YELLOW}Step 1.5: Checking Sibling Projects...${NC}" +PROJECT_ROOT=$(pwd) +PARENT_DIR=$(dirname "$PROJECT_ROOT") + +# Build Abada Tenda if available (just the image, not the container) +if [ -d "$PARENT_DIR/abada-tenda" ]; then + echo -e "${BLUE}Found ../abada-tenda. Building abada-tenda:dev image...${NC}" + (cd "$PARENT_DIR/abada-tenda" && docker build -t abada-tenda:dev .) +else + echo -e "${YELLOW}../abada-tenda not found. Skipping build.${NC}" +fi + +# Build Abada Orun if available (just the image, not the container) +if [ -d "$PARENT_DIR/abada-orun" ]; then + echo -e "${BLUE}Found ../abada-orun. Building abada-orun:dev image...${NC}" + (cd "$PARENT_DIR/abada-orun" && docker build -t abada-orun:dev .) +else + echo -e "${YELLOW}../abada-orun not found. Skipping build.${NC}" +fi + + +echo -e "\n${YELLOW}Step 2: Cleaning up existing environment...${NC}" +# We clean up to ensure fresh state, but we could make this optional +docker stop abada-engine 2>/dev/null || true +# We don't remove the image here to allow cache usage, but we force rebuild next + +echo -e "\n${YELLOW}Step 3: Building and starting ALL services...${NC}" +# We build abada-engine specifically to ensure the local jar is picked up, then up everything +docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build + +echo -e "\n${YELLOW}Step 4: Waiting for services to stabilize...${NC}" +sleep 10 + +echo -e "\n${GREEN}✓ Stack is up!${NC}" +echo -e "${BLUE}Services:${NC}" +echo -e "- Abada Engine: http://localhost:5601/abada/api" +echo -e "- Abada Tenda: http://localhost:5602" +echo -e "- Abada Orun: http://localhost:5603" +echo -e "- Grafana: http://localhost:3000 (admin/admin123)" +echo -e "- Jaeger: http://localhost:16686" +echo -e "- Traefik: http://localhost:8080" +echo -e "\n${YELLOW}To view logs:${NC} docker-compose -f docker-compose.yml -f docker-compose.dev.yml logs -f" diff --git a/scripts/dev-build.sh b/scripts/build-dev.sh similarity index 100% rename from scripts/dev-build.sh rename to scripts/build-dev.sh diff --git a/scripts/push-to-dockerhub.sh b/scripts/push-to-dockerhub.sh new file mode 100755 index 0000000..b136ec9 --- /dev/null +++ b/scripts/push-to-dockerhub.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +# Build and Push Abada Platform Images to Docker Hub +# This script builds production-ready images and pushes them to Docker Hub + +set -e # Exit on error + +# Configuration +DOCKER_USERNAME="${DOCKER_USERNAME:-}" +VERSION="${VERSION:-latest}" +PLATFORM_DIR="$(dirname "$(dirname "$(dirname "$(realpath "$0")")")")" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Function to print colored messages +print_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# Function to check if Docker is running +check_docker() { + if ! docker info > /dev/null 2>&1; then + print_error "Docker is not running. Please start Docker and try again." + exit 1 + fi + print_info "Docker is running" +} + +# Function to login to Docker Hub +docker_login() { + if [ -z "$DOCKER_USERNAME" ]; then + print_error "DOCKER_USERNAME environment variable is not set." + echo "Please run: export DOCKER_USERNAME=your_dockerhub_username" + exit 1 + fi + + print_info "Logging into Docker Hub as $DOCKER_USERNAME..." + if ! docker login -u "$DOCKER_USERNAME"; then + print_error "Docker Hub login failed" + exit 1 + fi + print_info "Successfully logged into Docker Hub" +} + +# Function to build and push an image +build_and_push() { + local component=$1 + local context_dir=$2 + local dockerfile=$3 + local image_name="${DOCKER_USERNAME}/${component}" + local full_tag="${image_name}:${VERSION}" + local latest_tag="${image_name}:latest" + + print_info "Building $component..." + print_info "Context: $context_dir" + print_info "Dockerfile: $dockerfile" + + # Build the image + if docker build -f "$dockerfile" -t "$full_tag" -t "$latest_tag" "$context_dir"; then + print_info "Successfully built $component" + else + print_error "Failed to build $component" + return 1 + fi + + # Push the versioned tag + print_info "Pushing $full_tag..." + if docker push "$full_tag"; then + print_info "Successfully pushed $full_tag" + else + print_error "Failed to push $full_tag" + return 1 + fi + + # Push the latest tag (only if VERSION is not 'latest') + if [ "$VERSION" != "latest" ]; then + print_info "Pushing $latest_tag..." + if docker push "$latest_tag"; then + print_info "Successfully pushed $latest_tag" + else + print_error "Failed to push $latest_tag" + return 1 + fi + fi + + print_info "✓ Completed $component" +} + +# Main execution +main() { + print_info "=== Abada Platform Docker Hub Push Script ===" + print_info "Platform directory: $PLATFORM_DIR" + print_info "Version: $VERSION" + echo "" + + # Check prerequisites + check_docker + docker_login + echo "" + + # Build and push each component + print_info "=== Building and Pushing Images ===" + echo "" + + # 1. Abada Engine + print_info "--- Building Abada Engine ---" + build_and_push \ + "abada-engine" \ + "$PLATFORM_DIR/abada-engine" \ + "$PLATFORM_DIR/abada-engine/Dockerfile.prod" + echo "" + + # 2. Abada Tenda + print_info "--- Building Abada Tenda ---" + build_and_push \ + "abada-tenda" \ + "$PLATFORM_DIR/abada-tenda" \ + "$PLATFORM_DIR/abada-tenda/Dockerfile.prod" + echo "" + + # 3. Abada Orun + print_info "--- Building Abada Orun ---" + build_and_push \ + "abada-orun" \ + "$PLATFORM_DIR/abada-orun" \ + "$PLATFORM_DIR/abada-orun/Dockerfile.prod" + echo "" + + # Summary + print_info "=== Build and Push Complete ===" + echo "" + print_info "Successfully built and pushed the following images:" + echo " - ${DOCKER_USERNAME}/abada-engine:${VERSION}" + echo " - ${DOCKER_USERNAME}/abada-tenda:${VERSION}" + echo " - ${DOCKER_USERNAME}/abada-orun:${VERSION}" + + if [ "$VERSION" != "latest" ]; then + echo "" + print_info "Also tagged as :latest" + fi + + echo "" + print_info "Users can now run the platform with:" + echo " docker-compose -f docker-compose.hub.yml up -d" +} + +# Run main function +main diff --git a/scripts/release-compose.sh b/scripts/release-compose.sh new file mode 100755 index 0000000..c3127fb --- /dev/null +++ b/scripts/release-compose.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Script to merge docker-compose files for release +# Generates a single docker-compose.release.yml file + +set -e + +# Configuration +VERSION="${VERSION:-latest}" +PLATFORM_DIR="$(dirname "$(dirname "$(realpath "$0")")")" +OUTPUT_FILE="$PLATFORM_DIR/release/docker-compose.release.yml" + +# Colors +GREEN='\033[0;32m' +NC='\033[0m' + +echo -e "${GREEN}[INFO]${NC} Generating release compose file..." + +# Use docker compose config to merge files +# We merge: base + prod + hub +# This gives us: +# - All services from base +# - Prod configurations (postgres, multiple replicas, etc) +# - Hub images (instead of local build) + +if ! docker compose \ + -f "$PLATFORM_DIR/docker-compose.yml" \ + -f "$PLATFORM_DIR/docker-compose.prod.yml" \ + -f "$PLATFORM_DIR/docker-compose.hub.yml" \ + config > "$OUTPUT_FILE"; then + echo "Error: Failed to generate compose config" + exit 1 +fi + +echo -e "${GREEN}[INFO]${NC} Successfully generated: $OUTPUT_FILE" +echo "You can test it with:" +echo "cd release && docker compose -f docker-compose.release.yml up -d" diff --git a/src/main/java/com/abada/engine/core/ProcessInstance.java b/src/main/java/com/abada/engine/core/ProcessInstance.java index 3c8bed8..8fc7d2d 100644 --- a/src/main/java/com/abada/engine/core/ProcessInstance.java +++ b/src/main/java/com/abada/engine/core/ProcessInstance.java @@ -4,9 +4,6 @@ import com.abada.engine.dto.UserTaskPayload; import com.abada.engine.spi.DelegateExecution; import com.abada.engine.spi.JavaDelegate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.time.Instant; import java.util.*; @@ -24,8 +21,6 @@ public class ProcessInstance { private final Map joinExpectedTokens = new HashMap<>(); private final Map> joinArrivedTokens = new HashMap<>(); - private static final Logger log = LoggerFactory.getLogger(ProcessInstance.class); - public ProcessInstance(ParsedProcessDefinition definition) { this.id = UUID.randomUUID().toString(); this.definition = definition; diff --git a/src/main/java/com/abada/engine/persistence/repository/ExternalTaskRepository.java b/src/main/java/com/abada/engine/persistence/repository/ExternalTaskRepository.java index 277e9c8..0e64ba9 100644 --- a/src/main/java/com/abada/engine/persistence/repository/ExternalTaskRepository.java +++ b/src/main/java/com/abada/engine/persistence/repository/ExternalTaskRepository.java @@ -5,7 +5,6 @@ import org.springframework.stereotype.Repository; import java.time.Instant; -import java.util.List; import java.util.Optional; @Repository @@ -15,11 +14,12 @@ public interface ExternalTaskRepository extends JpaRepository findFirstByTopicNameAndStatusOrTopicNameAndLockExpirationTimeLessThan(String topicName, ExternalTaskEntity.Status status, String topicName2, Instant now); + Optional findFirstByTopicNameAndStatusOrTopicNameAndLockExpirationTimeLessThan(String topicName, + ExternalTaskEntity.Status status, String topicName2, Instant now); }