diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index af054e3..3fe1666 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -127,26 +127,44 @@ docker-migrations: - *publish_script # ─── TRIGGER DEPLOY (downstream pipeline) ────── +# GitLab quirk: variables: в trigger job НЕ интерполируются от upstream global +# variables напрямую — `$IMAGE_TAG` передавался как литерал. Workaround: +# resolve-tag job записывает значение в dotenv artifact, тогда оно становится +# job-level variable trigger job'а и interpolation работает. + +resolve-tag: + stage: trigger-deploy + image: repo.nstart.cloud/library/alpine:3.20 + needs: [maven-package] + script: + - echo "RESOLVED_IMAGE_TAG=$IMAGE_TAG" > resolved.env + - cat resolved.env + artifacts: + reports: + dotenv: resolved.env + trigger-deploy-staging: stage: trigger-deploy + needs: [resolve-tag] trigger: project: 2-6/2-6-4/terravault/ordinis-infra branch: main strategy: depend variables: - UPSTREAM_IMAGE_TAG: $IMAGE_TAG + UPSTREAM_IMAGE_TAG: $RESOLVED_IMAGE_TAG DEPLOY_ENV: staging rules: - if: '$CI_COMMIT_BRANCH == "main"' trigger-deploy-prod: stage: trigger-deploy + needs: [resolve-tag] trigger: project: 2-6/2-6-4/terravault/ordinis-infra branch: main strategy: depend variables: - UPSTREAM_IMAGE_TAG: $IMAGE_TAG + UPSTREAM_IMAGE_TAG: $RESOLVED_IMAGE_TAG DEPLOY_ENV: prod rules: - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2083eb0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,144 @@ +# Локальный dev: PG + Kafka + Redis + 3 сервиса. +# Vault и config-server отключены через профиль `dev` (см. application.yml). +# +# Использование: +# docker compose up postgres kafka redis # инфра +# mvn -pl ordinis-migrations spring-boot:run # миграции (или liquibase отдельно) +# docker compose up app read-api projection-writer # все три сервиса +# +# Образа сервисов pull'аются из repo.nstart.cloud/terravault (CI build). +# Для собственной сборки: `mvn package && docker compose build`. + +x-common-env: &common-env + SPRING_PROFILES_ACTIVE: dev + ENVIRONMENT: dev + ORDINIS_PG_HOST: postgres + ORDINIS_PG_PORT: "5432" + ORDINIS_PG_DB: ordinis + ORDINIS_PG_USER: ordinis_app + ORDINIS_PG_PASSWORD: ordinis_app_dev + ORDINIS_KAFKA_BOOTSTRAP: kafka:9092 + ORDINIS_KAFKA_SECURITY: PLAINTEXT + ORDINIS_KAFKA_USER: "" + ORDINIS_KAFKA_PASSWORD: "" + ORDINIS_REDIS_HOST: redis + ORDINIS_REDIS_PORT: "6379" + ORDINIS_REDIS_PASSWORD: "" + +services: + postgres: + image: repo.nstart.cloud/library/postgis/postgis:18-3.6 + container_name: ordinis-postgres + environment: + POSTGRES_DB: ordinis + POSTGRES_USER: ordinis_app + POSTGRES_PASSWORD: ordinis_app_dev + ports: + - "5432:5432" + volumes: + - pg-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ordinis_app -d ordinis"] + interval: 5s + timeout: 3s + retries: 10 + + kafka: + image: repo.nstart.cloud/library/apache/kafka:4.2.0 + container_name: ordinis-kafka + ports: + - "9092:9092" + environment: + KAFKA_NODE_ID: 1 + KAFKA_PROCESS_ROLES: broker,controller + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT + KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093 + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 + KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1 + CLUSTER_ID: ordinis-dev-kafka + + redis: + image: repo.nstart.cloud/library/redis:7-alpine + container_name: ordinis-redis + ports: + - "6379:6379" + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + migrations: + image: repo.nstart.cloud/terravault/ordinis-migrations:latest + container_name: ordinis-migrations + depends_on: + postgres: + condition: service_healthy + environment: + ORDINIS_PG_USER: ordinis_app + ORDINIS_PG_PASSWORD: ordinis_app_dev + command: + - sh + - -c + - | + cd /liquibase + liquibase \ + --search-path=/liquibase/changelog \ + --changelog-file=master.xml \ + --url="jdbc:postgresql://postgres:5432/ordinis" \ + --username="$$ORDINIS_PG_USER" \ + --password="$$ORDINIS_PG_PASSWORD" \ + update + + app: + image: repo.nstart.cloud/terravault/ordinis-app:latest + container_name: ordinis-app + depends_on: + postgres: + condition: service_healthy + kafka: + condition: service_started + migrations: + condition: service_completed_successfully + environment: + <<: *common-env + ports: + - "8080:8080" + + read-api: + image: repo.nstart.cloud/terravault/ordinis-read-api:latest + container_name: ordinis-read-api + depends_on: + postgres: + condition: service_healthy + migrations: + condition: service_completed_successfully + environment: + <<: *common-env + ports: + - "8081:8081" + + projection-writer: + image: repo.nstart.cloud/terravault/ordinis-projection-writer:latest + container_name: ordinis-projection-writer + depends_on: + postgres: + condition: service_healthy + kafka: + condition: service_started + redis: + condition: service_healthy + migrations: + condition: service_completed_successfully + environment: + <<: *common-env + ports: + - "8082:8082" + +volumes: + pg-data: diff --git a/ordinis-projection-writer/src/main/resources/application.yml b/ordinis-projection-writer/src/main/resources/application.yml index e4b118b..5ae10ca 100644 --- a/ordinis-projection-writer/src/main/resources/application.yml +++ b/ordinis-projection-writer/src/main/resources/application.yml @@ -3,12 +3,16 @@ spring: name: ordinis-projection-writer profiles: active: ${SPRING_PROFILES_ACTIVE:dev} - -server: - port: 8082 - shutdown: graceful + # projection-writer — не web app (Kafka consumer + Redis writer). Web-сервер + # нужен только под актуатор (probes/metrics/prometheus); живёт на отдельном + # management-порту. + main: + web-application-type: none management: + server: + port: 8082 + address: 0.0.0.0 endpoints: web: exposure: