chore: сохранение текущих изменений (deploy local-bundle/local-jar, request-service, slots UI markedObjectIds)

Безопасный коммит незакоммиченной работы перед реализацией бронирования слотов.
Вне коммита оставлены: package-lock.json (пустой, мусор), requests.json (scratch-данные).
This commit is contained in:
Дмитрий Соловьев
2026-06-11 14:00:12 +03:00
parent 6689351ef0
commit 345529cde0
36 changed files with 1674 additions and 37 deletions
+24 -1
View File
@@ -1,5 +1,18 @@
COMPOSE_PROJECT_NAME=pcp-local
USE_EXTERNAL_INFRA=false
PCP_DOCKER_NETWORK=pcp-local_default
PCP_DOCKER_NETWORK_EXTERNAL=false
# Existing allinone infra example:
# USE_EXTERNAL_INFRA=true
# PCP_DOCKER_NETWORK=allinone_camunda
# PCP_DOCKER_NETWORK_EXTERNAL=true
# EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
# EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
# CAMUNDA_CLIENT_ENABLED=true
# CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
PCP_IMAGE_TAG=local
POSTGRES_IMAGE=postgis/postgis:16-3.4
@@ -8,14 +21,24 @@ KAFKA_IMAGE=apache/kafka:3.7.2
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_PORT=5432
PCP_POSTGRES_HOST=postgres
PCP_POSTGRES_PORT=5432
EXTERNAL_POSTGRES_CONTAINER=
KAFKA_PORT=29092
PCP_KAFKA_HOST=kafka
PCP_KAFKA_PORT=9092
EXTERNAL_KAFKA_CONTAINER=
CAMUNDA_CLIENT_ENABLED=false
CAMUNDA_GRPC_ADDRESS=http://host.docker.internal:26500
CONFIG_SERVER_PORT=38888
PCP_ADMIN_PORT=7000
PCP_TLE_MONITORING_PORT=7001
PCP_COMPLEX_MISSION_PORT=7002
PCP_BALLISTICS_PORT=7003
PCP_ROUTE_PROCESSING_PORT=7004
PCP_REQUEST_PORT=7005
PCP_SLOTS_PORT=7006
PCP_UI_PORT=7008
+127 -2
View File
@@ -2,6 +2,9 @@
Локальный bundle предназначен для запуска PCP на машине с Docker без GitLab Config Repo, Kubernetes и Helm.
В bundle входят backend-сервисы PCP, кроме `tle-monitoring-service`; отдельный frontend
`pcp-tgu-ops-ui` также не включается.
## Состав
- `docker-compose.yml` - локальная схема запуска.
@@ -15,6 +18,72 @@
- `scripts/stop.sh` - остановка compose stack.
- `scripts/status.sh` - статус контейнеров.
## Локальный запуск без архива
Для запуска на той же машине, где собираются images, архив и `docker save` не нужны.
Используйте один скрипт:
```bash
./deploy/local-bundle/run-local.sh start
```
Скрипт:
- создаёт `.env` из `.env.example`, если его ещё нет;
- собирает `bootJar` в Gradle offline mode;
- собирает локальные Docker images `pcp/<service>:<PCP_IMAGE_TAG>`;
- запускает `docker compose`.
Для вашего allinone Postgres/Kafka/Camunda перед первым запуском настройте
`deploy/local-bundle/.env`:
```env
USE_EXTERNAL_INFRA=true
PCP_DOCKER_NETWORK=allinone_camunda
PCP_DOCKER_NETWORK_EXTERNAL=true
PCP_POSTGRES_HOST=postgres
PCP_POSTGRES_PORT=5432
PCP_KAFKA_HOST=kafka
PCP_KAFKA_PORT=9092
EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
CAMUNDA_CLIENT_ENABLED=true
CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
```
Команды:
```bash
./deploy/local-bundle/run-local.sh start
./deploy/local-bundle/run-local.sh status
./deploy/local-bundle/run-local.sh logs
./deploy/local-bundle/run-local.sh stop
```
## Пересборка одного сервиса
После первого запуска всего стека можно пересобирать и перезапускать только один сервис:
```bash
./deploy/local-bundle/services/pcp-request-service.sh
```
Это выполнит:
- `bootJar` только для `pcp-request-service`;
- `docker build` только для `pcp/pcp-request-service:<PCP_IMAGE_TAG>`;
- `docker compose up -d --no-deps --force-recreate pcp-request-service`.
Доступны wrapper-скрипты в `deploy/local-bundle/services/` для каждого сервиса.
То же самое можно вызвать через общий скрипт:
```bash
./deploy/local-bundle/run-service.sh pcp-request-service
./deploy/local-bundle/run-service.sh pcp-request-service build
./deploy/local-bundle/run-service.sh pcp-request-service logs
./deploy/local-bundle/run-service.sh pcp-request-service stop
```
## Сборка архива
Из корня репозитория:
@@ -38,6 +107,7 @@ deploy/local-bundle/build/pcp-local-bundle-<version>.tar.gz
Скрипт сборки:
- собирает `bootJar` для разворачиваемых сервисов;
- запускает Gradle в offline mode по умолчанию;
- собирает Docker images сервисов;
- сохраняет PCP service images в один `images/pcp-services.tar`;
- по умолчанию не сохраняет публичные infra images, чтобы не раздувать архив;
@@ -61,6 +131,41 @@ KOTLIN_DAEMON_JVMARGS="-Xmx3g -XX:MaxMetaspaceSize=768m" \
./deploy/local-bundle/build-local-bundle.sh
```
Gradle offline mode включён по умолчанию:
```bash
GRADLE_OFFLINE=true ./deploy/local-bundle/build-local-bundle.sh
```
Если нужно один раз прогреть локальный Gradle cache, временно отключите offline mode:
```bash
GRADLE_OFFLINE=false ./deploy/local-bundle/build-local-bundle.sh
```
Важно: `GRADLE_OFFLINE=true` отключает сетевой резолв зависимостей Gradle, но Docker всё равно
должен иметь локально доступный base image. Для local bundle сервисные Dockerfile собираются с
локальным override:
```text
LOCAL_BUNDLE_RUNTIME_IMAGE=bellsoft/liberica-openjre-alpine:21.0.5
```
Поэтому перед полностью offline Docker-сборкой подтяните или импортируйте:
```bash
docker pull bellsoft/liberica-openjre-alpine:21.0.5
```
Для полностью переносимого архива с infra images заранее подтяните Postgres/Kafka и включите их
сохранение:
```bash
docker pull postgis/postgis:16-3.4
docker pull apache/kafka:3.7.2
INCLUDE_INFRA_IMAGES=true ./deploy/local-bundle/build-local-bundle.sh
```
## Запуск на локальной машине
Распаковать архив:
@@ -72,6 +177,26 @@ cd pcp-local-bundle-<version>
Проверить `.env` и при необходимости изменить порты.
Если Postgres/Kafka/Camunda уже подняты внешним allinone compose, например в сети
`allinone_camunda`, включите external infra mode в `.env`:
```env
USE_EXTERNAL_INFRA=true
PCP_DOCKER_NETWORK=allinone_camunda
PCP_DOCKER_NETWORK_EXTERNAL=true
PCP_POSTGRES_HOST=postgres
PCP_POSTGRES_PORT=5432
PCP_KAFKA_HOST=kafka
PCP_KAFKA_PORT=9092
EXTERNAL_POSTGRES_CONTAINER=allinone-postgres-1
EXTERNAL_KAFKA_CONTAINER=allinone-kafka-1
CAMUNDA_CLIENT_ENABLED=true
CAMUNDA_GRPC_ADDRESS=http://orchestration:26500
```
В этом режиме `scripts/start.sh` не поднимает свои `postgres` и `kafka`, а сервисы PCP
подключаются к уже существующим контейнерам через общую Docker network.
Импортировать images:
```bash
@@ -109,9 +234,9 @@ cd pcp-local-bundle-<version>
- Config Server: `http://localhost:38888`
- Spring Boot Admin: `http://localhost:7000`
- TLE Monitoring: `http://localhost:7001`
- Complex Mission: `http://localhost:7002`
- Ballistics: `http://localhost:7003`
- Route Processing: `http://localhost:7004`
- Request Service: `http://localhost:7005`
- Slots Service: `http://localhost:7006`
- UI: `http://localhost:7008`
@@ -178,13 +303,13 @@ SPRING_CLOUD_CONFIG_LABEL=
- `pcp_ballistics`
- `pcp_requests`
- `pcp_route_processing`
- `pcp_missions`
- `pcp_slots`
- `pcp_complex_plan`
- `pcp_satellite_catalog`
- `pcp_stations`
- `pcp_tgu`
- `pcp_tle`
- `pcp_satellites`
Таблицы, схемы и seed data вручную не создаются. Схемы создаются существующими Flyway migrations внутри сервисов при старте приложений.
+15 -3
View File
@@ -26,6 +26,7 @@ service_names=(
pcp-satellite-catalog-service
pcp-ballistics-service
pcp-request-service
pcp-route-processing-service
slots-service
pcp-complex-mission-service
pcp-mission-planing-service
@@ -33,13 +34,14 @@ service_names=(
pcp-dynamic-plan-service
pcp-stations-service
pcp-ui-service
tle-monitoring-service
pcp-tgu-service
)
gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
gradle_offline="${GRADLE_OFFLINE:-true}"
runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
include_infra_images="${INCLUDE_INFRA_IMAGES:-false}"
gradle_common_args=(
@@ -49,6 +51,10 @@ gradle_common_args=(
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
)
if [[ "$gradle_offline" == "true" ]]; then
gradle_common_args+=("--offline")
fi
infra_images=(
"${POSTGRES_IMAGE:-postgis/postgis:16-3.4}"
"${KAFKA_IMAGE:-apache/kafka:3.7.2}"
@@ -117,9 +123,11 @@ echo "Building bootJar artifacts..."
echo "Gradle max workers: $gradle_max_workers"
echo "Gradle JVM args: $gradle_jvmargs"
echo "Kotlin daemon JVM args: $kotlin_daemon_jvmargs"
echo "Gradle offline mode: $gradle_offline"
echo "Local bundle runtime image: $runtime_image"
for service_name in "${service_names[@]}"; do
echo "Building bootJar for $service_name..."
"$repo_root/gradlew" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
done
rm -rf "$dist_dir" "$docker_contexts_dir" "$archive_path"
@@ -132,7 +140,11 @@ for service_name in "${service_names[@]}"; do
context_dir="$docker_contexts_dir/$service_name"
copy_single_boot_jar "$service_name" "$context_dir"
docker build --file "$context_dir/Dockerfile" --tag "$image_name" "$context_dir"
docker build \
--build-arg "RUNTIME_IMAGE=$runtime_image" \
--file "$context_dir/Dockerfile" \
--tag "$image_name" \
"$context_dir"
service_images+=("$image_name")
done
+23 -13
View File
@@ -8,9 +8,17 @@ x-pcp-service-env: &pcp-service-env
SPRING_CLOUD_CONFIG_LABEL: ""
SPRING_KAFKA_ADMIN_AUTO_CREATE: "true"
SPRING_KAFKA_LISTENER_AUTO_STARTUP: "true"
PCP_POSTGRES_HOST: ${PCP_POSTGRES_HOST:-postgres}
PCP_POSTGRES_PORT: ${PCP_POSTGRES_PORT:-5432}
PCP_KAFKA_HOST: ${PCP_KAFKA_HOST:-kafka}
PCP_KAFKA_PORT: ${PCP_KAFKA_PORT:-9092}
CAMUNDA_CLIENT_ENABLED: ${CAMUNDA_CLIENT_ENABLED:-false}
CAMUNDA_GRPC_ADDRESS: ${CAMUNDA_GRPC_ADDRESS:-http://host.docker.internal:26500}
x-pcp-service-common: &pcp-service-common
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
spring-cloud-config-server:
condition: service_started
@@ -64,11 +72,8 @@ services:
spring-cloud-config-server:
image: pcp/spring-cloud-config-server:${PCP_IMAGE_TAG:-local}
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
kafka:
condition: service_started
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
SPRING_PROFILES_ACTIVE: local
CONFIG_NATIVE_SEARCH_LOCATIONS: file:/config-repo
@@ -86,14 +91,6 @@ services:
ports:
- "${PCP_ADMIN_PORT:-7000}:7000"
tle-monitoring-service:
<<: *pcp-service-common
image: pcp/tle-monitoring-service:${PCP_IMAGE_TAG:-local}
environment:
<<: *pcp-service-env
ports:
- "${PCP_TLE_MONITORING_PORT:-7001}:7001"
pcp-complex-mission-service:
<<: *pcp-service-common
image: pcp/pcp-complex-mission-service:${PCP_IMAGE_TAG:-local}
@@ -118,6 +115,14 @@ services:
ports:
- "${PCP_REQUEST_PORT:-7005}:7005"
pcp-route-processing-service:
<<: *pcp-service-common
image: pcp/pcp-route-processing-service:${PCP_IMAGE_TAG:-local}
environment:
<<: *pcp-service-env
ports:
- "${PCP_ROUTE_PROCESSING_PORT:-7004}:7004"
slots-service:
<<: *pcp-service-common
image: pcp/slots-service:${PCP_IMAGE_TAG:-local}
@@ -193,3 +198,8 @@ services:
volumes:
postgres-data:
kafka-data:
networks:
default:
name: ${PCP_DOCKER_NETWORK:-pcp-local_default}
external: ${PCP_DOCKER_NETWORK_EXTERNAL:-false}
+199
View File
@@ -0,0 +1,199 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "$script_dir/../.." && pwd)"
env_file="$script_dir/.env"
env_example_file="$script_dir/.env.example"
docker_contexts_dir="$script_dir/build/local-docker-contexts"
service_names=(
spring-cloud-config-server
pcp-srpring-boot-admin-server
pcp-satellite-catalog-service
pcp-ballistics-service
pcp-request-service
pcp-route-processing-service
slots-service
pcp-complex-mission-service
pcp-mission-planing-service
pcp-coverage-scheme-service
pcp-dynamic-plan-service
pcp-stations-service
pcp-ui-service
pcp-tgu-service
)
ensure_env_file() {
if [[ ! -f "$env_file" && -f "$env_example_file" ]]; then
cp "$env_example_file" "$env_file"
echo "Created $env_file from .env.example"
fi
}
ensure_source_config_repo_dir() {
if grep -q '^CONFIG_REPO_DIR=' "$env_file"; then
sed -i "s#^CONFIG_REPO_DIR=.*#CONFIG_REPO_DIR=$repo_root/config-repo#" "$env_file"
else
printf '\nCONFIG_REPO_DIR=%s/config-repo\n' "$repo_root" >> "$env_file"
fi
}
load_env() {
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
}
require_command() {
local command_name="$1"
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "$command_name is required." >&2
exit 1
fi
}
compose() {
if docker compose version >/dev/null 2>&1; then
docker compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
elif command -v docker-compose >/dev/null 2>&1; then
docker-compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
else
echo "docker compose or docker-compose is required." >&2
exit 1
fi
}
copy_single_boot_jar() {
local service_name="$1"
local context_dir="$2"
local jar_count
local jar_file
jar_count="$(
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l
)"
if [[ "$jar_count" != "1" ]]; then
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
exit 1
fi
jar_file="$(
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1
)"
mkdir -p "$context_dir/build/libs"
cp "$repo_root/services/$service_name/Dockerfile" "$context_dir/Dockerfile"
cp "$jar_file" "$context_dir/build/libs/app.jar"
}
build_images() {
local gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
local gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
local kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
local gradle_offline="${GRADLE_OFFLINE:-true}"
local runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
local image_tag="${PCP_IMAGE_TAG:-local}"
local service_name
local image_name
local context_dir
local gradle_common_args=(
"--no-parallel"
"--max-workers=$gradle_max_workers"
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
)
if [[ "$gradle_offline" == "true" ]]; then
gradle_common_args+=("--offline")
fi
echo "Building local Docker images..."
echo "Gradle offline mode: $gradle_offline"
echo "Local image tag: $image_tag"
echo "Runtime image: $runtime_image"
for service_name in "${service_names[@]}"; do
echo "Building bootJar for $service_name..."
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
done
rm -rf "$docker_contexts_dir"
mkdir -p "$docker_contexts_dir"
for service_name in "${service_names[@]}"; do
image_name="pcp/$service_name:$image_tag"
context_dir="$docker_contexts_dir/$service_name"
copy_single_boot_jar "$service_name" "$context_dir"
echo "Building Docker image $image_name..."
docker build \
--build-arg "RUNTIME_IMAGE=$runtime_image" \
--file "$context_dir/Dockerfile" \
--tag "$image_name" \
"$context_dir"
done
}
usage() {
cat <<'EOF'
Usage:
./deploy/local-bundle/run-local.sh [command]
Commands:
start Build service images locally and start docker compose.
restart Stop compose stack, then build and start.
build Build service images locally, without starting compose.
stop Stop compose stack.
status Show compose status.
logs Follow compose logs.
EOF
}
start_local() {
build_images
"$script_dir/scripts/start.sh"
}
command="${1:-start}"
case "$command" in
help|-h|--help)
usage
exit 0
;;
esac
ensure_env_file
ensure_source_config_repo_dir
load_env
require_command docker
case "$command" in
start)
start_local
;;
restart)
"$script_dir/scripts/stop.sh"
start_local
;;
build)
build_images
;;
stop)
"$script_dir/scripts/stop.sh"
;;
status)
"$script_dir/scripts/status.sh"
;;
logs)
compose logs -f
;;
*)
usage >&2
exit 1
;;
esac
+242
View File
@@ -0,0 +1,242 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "$script_dir/../.." && pwd)"
env_file="$script_dir/.env"
env_example_file="$script_dir/.env.example"
docker_contexts_dir="$script_dir/build/local-docker-contexts"
service_names=(
spring-cloud-config-server
pcp-srpring-boot-admin-server
pcp-satellite-catalog-service
pcp-ballistics-service
pcp-request-service
pcp-route-processing-service
slots-service
pcp-complex-mission-service
pcp-mission-planing-service
pcp-coverage-scheme-service
pcp-dynamic-plan-service
pcp-stations-service
pcp-ui-service
pcp-tgu-service
)
usage() {
cat <<'EOF'
Usage:
./deploy/local-bundle/run-service.sh SERVICE [command]
Commands:
restart Build SERVICE bootJar, rebuild its Docker image and recreate only this compose service.
build Build SERVICE bootJar and Docker image, without restarting container.
stop Stop SERVICE container.
logs Follow SERVICE logs.
Examples:
./deploy/local-bundle/run-service.sh pcp-request-service
./deploy/local-bundle/run-service.sh pcp-request-service build
EOF
}
ensure_env_file() {
if [[ ! -f "$env_file" && -f "$env_example_file" ]]; then
cp "$env_example_file" "$env_file"
echo "Created $env_file from .env.example"
fi
}
ensure_source_config_repo_dir() {
if grep -q '^CONFIG_REPO_DIR=' "$env_file"; then
sed -i "s#^CONFIG_REPO_DIR=.*#CONFIG_REPO_DIR=$repo_root/config-repo#" "$env_file"
else
printf '\nCONFIG_REPO_DIR=%s/config-repo\n' "$repo_root" >> "$env_file"
fi
}
load_env() {
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
}
require_command() {
local command_name="$1"
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "$command_name is required." >&2
exit 1
fi
}
compose() {
if docker compose version >/dev/null 2>&1; then
docker compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
elif command -v docker-compose >/dev/null 2>&1; then
docker-compose --project-directory "$script_dir" -f "$script_dir/docker-compose.yml" "$@"
else
echo "docker compose or docker-compose is required." >&2
exit 1
fi
}
is_known_service() {
local service_name="$1"
local known_service_name
for known_service_name in "${service_names[@]}"; do
if [[ "$known_service_name" == "$service_name" ]]; then
return 0
fi
done
return 1
}
copy_single_boot_jar() {
local service_name="$1"
local context_dir="$2"
local jar_count
local jar_file
jar_count="$(
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | wc -l
)"
if [[ "$jar_count" != "1" ]]; then
echo "Expected exactly one bootJar for $service_name, found $jar_count:" >&2
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' -print >&2 || true
exit 1
fi
jar_file="$(
find "$repo_root/services/$service_name/build/libs" -maxdepth 1 -type f -name '*.jar' ! -name '*-plain.jar' | head -n 1
)"
mkdir -p "$context_dir/build/libs"
cp "$repo_root/services/$service_name/Dockerfile" "$context_dir/Dockerfile"
cp "$jar_file" "$context_dir/build/libs/app.jar"
}
build_service_image() {
local service_name="$1"
local gradle_max_workers="${GRADLE_MAX_WORKERS:-1}"
local gradle_jvmargs="${GRADLE_JVMARGS:--Xmx2g -Dfile.encoding=UTF-8}"
local kotlin_daemon_jvmargs="${KOTLIN_DAEMON_JVMARGS:--Xmx3g -XX:MaxMetaspaceSize=768m}"
local gradle_offline="${GRADLE_OFFLINE:-true}"
local runtime_image="${LOCAL_BUNDLE_RUNTIME_IMAGE:-bellsoft/liberica-openjre-alpine:21.0.5}"
local image_tag="${PCP_IMAGE_TAG:-local}"
local image_name="pcp/$service_name:$image_tag"
local context_dir="$docker_contexts_dir/$service_name"
local gradle_common_args=(
"--no-parallel"
"--max-workers=$gradle_max_workers"
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
)
if [[ "$gradle_offline" == "true" ]]; then
gradle_common_args+=("--offline")
fi
echo "Building bootJar for $service_name..."
"$repo_root/gradlew" --project-dir "$repo_root" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
rm -rf "$context_dir"
copy_single_boot_jar "$service_name" "$context_dir"
echo "Building Docker image $image_name..."
docker build \
--build-arg "RUNTIME_IMAGE=$runtime_image" \
--file "$context_dir/Dockerfile" \
--tag "$image_name" \
"$context_dir"
}
http_get() {
local url="$1"
if command -v curl >/dev/null 2>&1; then
curl -fsS "$url" >/dev/null
elif command -v wget >/dev/null 2>&1; then
wget -q -O /dev/null "$url"
else
return 2
fi
}
wait_for_config_server() {
local attempt
local url="http://localhost:${CONFIG_SERVER_PORT:-38888}/actuator/health"
for attempt in {1..90}; do
if http_get "$url"; then
echo "spring-cloud-config-server is ready: $url"
return 0
fi
sleep 2
done
echo "spring-cloud-config-server is not ready after 180 seconds: $url" >&2
exit 1
}
restart_service() {
local service_name="$1"
build_service_image "$service_name"
if [[ "$service_name" == "spring-cloud-config-server" ]]; then
compose up -d --no-deps --force-recreate "$service_name"
wait_for_config_server
return 0
fi
compose up -d spring-cloud-config-server
wait_for_config_server
compose up -d --no-deps --force-recreate "$service_name"
}
service_name="${1:-}"
command="${2:-restart}"
if [[ -z "$service_name" || "$service_name" == "help" || "$service_name" == "-h" || "$service_name" == "--help" ]]; then
usage
exit 0
fi
if ! is_known_service "$service_name"; then
echo "Unknown service: $service_name" >&2
echo "Known services:" >&2
printf ' %s\n' "${service_names[@]}" >&2
exit 1
fi
ensure_env_file
ensure_source_config_repo_dir
load_env
require_command docker
case "$command" in
restart)
restart_service "$service_name"
;;
build)
build_service_image "$service_name"
;;
stop)
compose stop "$service_name"
;;
logs)
compose logs -f "$service_name"
;;
help|-h|--help)
usage
;;
*)
usage >&2
exit 1
;;
esac
+11 -2
View File
@@ -25,6 +25,10 @@ ensure_env_file() {
}
ensure_env_file
set -a
# shellcheck disable=SC1091
source "$bundle_dir/.env"
set +a
if [[ ! -d "$images_dir" ]]; then
echo "Images directory not found: $images_dir" >&2
@@ -49,7 +53,12 @@ if [[ -f "$images_dir/public-images.txt" ]]; then
fi
cd "$bundle_dir"
echo "Starting postgres, kafka and spring-cloud-config-server..."
compose up -d postgres kafka spring-cloud-config-server
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
echo "Using external infrastructure. Starting spring-cloud-config-server only."
compose up -d spring-cloud-config-server
else
echo "Starting postgres, kafka and spring-cloud-config-server..."
compose up -d postgres kafka spring-cloud-config-server
fi
echo "Images imported and base services requested."
+53 -6
View File
@@ -43,6 +43,26 @@ wait_for_postgres() {
exit 1
}
wait_for_external_postgres() {
local container_name="${EXTERNAL_POSTGRES_CONTAINER:-}"
local attempt
if [[ -z "$container_name" ]]; then
echo "EXTERNAL_POSTGRES_CONTAINER is required when USE_EXTERNAL_INFRA=true and SKIP_DB_INIT is not true." >&2
exit 1
fi
for attempt in {1..60}; do
if docker exec "$container_name" pg_isready -U "${POSTGRES_USER:-postgres}" -d postgres >/dev/null 2>&1; then
return 0
fi
sleep 2
done
echo "External Postgres is not ready after 120 seconds: $container_name" >&2
exit 1
}
create_database_if_missing() {
local db_name="$1"
local exists
@@ -61,16 +81,35 @@ create_database_if_missing() {
compose exec -T postgres createdb -U "${POSTGRES_USER:-postgres}" "$db_name"
}
create_external_database_if_missing() {
local db_name="$1"
local container_name="${EXTERNAL_POSTGRES_CONTAINER:-}"
local exists
exists="$(
docker exec "$container_name" psql -U "${POSTGRES_USER:-postgres}" -d postgres -tAc \
"SELECT 1 FROM pg_database WHERE datname = '$db_name'" | tr -d '[:space:]'
)"
if [[ "$exists" == "1" ]]; then
echo "Database already exists: $db_name"
return 0
fi
echo "Creating database: $db_name"
docker exec "$container_name" createdb -U "${POSTGRES_USER:-postgres}" "$db_name"
}
databases=(
pcp_ballistics
pcp_requests
pcp_route_processing
pcp_missions
pcp_slots
pcp_complex_plan
pcp_satellite_catalog
pcp_stations
pcp_tgu
pcp_tle
pcp_satellites
)
@@ -78,12 +117,20 @@ ensure_env_file
load_env
cd "$bundle_dir"
compose up -d postgres
wait_for_postgres
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
wait_for_external_postgres
for db_name in "${databases[@]}"; do
create_database_if_missing "$db_name"
done
for db_name in "${databases[@]}"; do
create_external_database_if_missing "$db_name"
done
else
compose up -d postgres
wait_for_postgres
for db_name in "${databases[@]}"; do
create_database_if_missing "$db_name"
done
fi
echo "Database initialization completed. Tables are left to service Flyway migrations."
echo "No schema objects or seed data were created by this script."
+37 -5
View File
@@ -72,11 +72,34 @@ wait_for_kafka() {
exit 1
}
wait_for_external_kafka() {
local container_name="${EXTERNAL_KAFKA_CONTAINER:-}"
local attempt
if [[ -z "$container_name" ]]; then
echo "External Kafka container is not configured; skipping Kafka readiness check."
return 0
fi
for attempt in {1..60}; do
if docker exec "$container_name" kafka-topics --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1 ||
docker exec "$container_name" kafka-topics.sh --bootstrap-server "${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}" --list >/dev/null 2>&1; then
echo "External Kafka is ready in container $container_name."
return 0
fi
sleep 2
done
echo "External Kafka is not ready after 120 seconds: $container_name" >&2
exit 1
}
app_services=(
pcp-srpring-boot-admin-server
pcp-satellite-catalog-service
pcp-ballistics-service
pcp-request-service
pcp-route-processing-service
slots-service
pcp-complex-mission-service
pcp-mission-planing-service
@@ -84,7 +107,6 @@ app_services=(
pcp-dynamic-plan-service
pcp-stations-service
pcp-ui-service
tle-monitoring-service
pcp-tgu-service
)
@@ -93,9 +115,16 @@ load_env
cd "$bundle_dir"
echo "Starting infrastructure..."
compose up -d postgres kafka
wait_for_kafka
if [[ "${USE_EXTERNAL_INFRA:-false}" == "true" ]]; then
echo "Using external infrastructure. Skipping local postgres/kafka startup."
echo "Postgres endpoint for services: ${PCP_POSTGRES_HOST:-postgres}:${PCP_POSTGRES_PORT:-5432}"
echo "Kafka endpoint for services: ${PCP_KAFKA_HOST:-kafka}:${PCP_KAFKA_PORT:-9092}"
wait_for_external_kafka
else
echo "Starting infrastructure..."
compose up -d postgres kafka
wait_for_kafka
fi
if [[ "${SKIP_DB_INIT:-false}" != "true" ]]; then
"$script_dir/init-db.sh"
@@ -106,7 +135,10 @@ compose up -d spring-cloud-config-server
wait_for_http "spring-cloud-config-server" "http://localhost:${CONFIG_SERVER_PORT:-38888}/actuator/health"
echo "Starting application services..."
compose up -d "${app_services[@]}"
for service_name in "${app_services[@]}"; do
echo "Starting $service_name..."
compose up -d "$service_name"
done
echo "Application startup requested."
compose ps
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-ballistics-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-complex-mission-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-coverage-scheme-service "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-dynamic-plan-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-mission-planing-service "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-request-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-route-processing-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-satellite-catalog-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-srpring-boot-admin-server "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-stations-service "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-tgu-service "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" pcp-ui-service "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" slots-service "$@"
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
exec "$script_dir/run-service.sh" spring-cloud-config-server "$@"