Init
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
COMPOSE_PROJECT_NAME=pcp-local
|
||||
|
||||
PCP_IMAGE_TAG=local
|
||||
|
||||
POSTGRES_IMAGE=postgis/postgis:16-3.4
|
||||
KAFKA_IMAGE=apache/kafka:3.7.2
|
||||
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=password
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
KAFKA_PORT=29092
|
||||
CONFIG_SERVER_PORT=38888
|
||||
|
||||
PCP_ADMIN_PORT=7000
|
||||
PCP_TLE_MONITORING_PORT=7001
|
||||
PCP_COMPLEX_MISSION_PORT=7002
|
||||
PCP_BALLISTICS_PORT=7003
|
||||
PCP_REQUEST_PORT=7005
|
||||
PCP_SLOTS_PORT=7006
|
||||
PCP_UI_PORT=7008
|
||||
PCP_STATIONS_PORT=7009
|
||||
PCP_MISSION_PORT=7010
|
||||
PCP_TGU_PORT=7011
|
||||
PCP_COVERAGE_SCHEME_PORT=7012
|
||||
PCP_SATELLITE_CATALOG_PORT=7013
|
||||
PCP_DYNAMIC_PLAN_PORT=7014
|
||||
|
||||
CONFIG_REPO_DIR=./config-repo
|
||||
@@ -0,0 +1,192 @@
|
||||
# PCP local Docker bundle
|
||||
|
||||
Локальный bundle предназначен для запуска PCP на машине с Docker без GitLab Config Repo, Kubernetes и Helm.
|
||||
|
||||
## Состав
|
||||
|
||||
- `docker-compose.yml` - локальная схема запуска.
|
||||
- `.env.example` - пример параметров запуска.
|
||||
- `.env` - создаётся сборочным скриптом в итоговом архиве.
|
||||
- `config-repo/` - локальный Spring Cloud Config repository.
|
||||
- `images/` - Docker images, сохранённые через `docker save`.
|
||||
- `scripts/import-images.sh` - импорт Docker images и запуск базовых сервисов.
|
||||
- `scripts/init-db.sh` - создание баз данных в одном Postgres контейнере.
|
||||
- `scripts/start.sh` - запуск инфраструктуры, config-server и приложений.
|
||||
- `scripts/stop.sh` - остановка compose stack.
|
||||
- `scripts/status.sh` - статус контейнеров.
|
||||
|
||||
## Сборка архива
|
||||
|
||||
Из корня репозитория:
|
||||
|
||||
```bash
|
||||
./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
Можно задать версию:
|
||||
|
||||
```bash
|
||||
LOCAL_BUNDLE_VERSION=1.0.0-local ./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
Результат будет создан в:
|
||||
|
||||
```bash
|
||||
deploy/local-bundle/build/pcp-local-bundle-<version>.tar.gz
|
||||
```
|
||||
|
||||
Скрипт сборки:
|
||||
|
||||
- собирает `bootJar` для разворачиваемых сервисов;
|
||||
- собирает Docker images сервисов;
|
||||
- сохраняет PCP service images в один `images/pcp-services.tar`;
|
||||
- по умолчанию не сохраняет публичные infra images, чтобы не раздувать архив;
|
||||
- копирует `docker-compose.yml`, `config-repo`, scripts и документацию;
|
||||
- формирует итоговый `tar.gz`.
|
||||
|
||||
Публичные images `postgis/postgis` и `apache/kafka` будут скачаны на целевой машине командой `docker compose up`, если их нет локально.
|
||||
|
||||
Если нужен полностью offline bundle, включите сохранение infra images:
|
||||
|
||||
```bash
|
||||
INCLUDE_INFRA_IMAGES=true ./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
По умолчанию сборка `bootJar` выполняется последовательно, чтобы не упираться в heap Kotlin compiler daemon на локальной машине. Параметры можно переопределить:
|
||||
|
||||
```bash
|
||||
GRADLE_MAX_WORKERS=1 \
|
||||
GRADLE_JVMARGS="-Xmx2g -Dfile.encoding=UTF-8" \
|
||||
KOTLIN_DAEMON_JVMARGS="-Xmx3g -XX:MaxMetaspaceSize=768m" \
|
||||
./deploy/local-bundle/build-local-bundle.sh
|
||||
```
|
||||
|
||||
## Запуск на локальной машине
|
||||
|
||||
Распаковать архив:
|
||||
|
||||
```bash
|
||||
tar -xzf pcp-local-bundle-<version>.tar.gz
|
||||
cd pcp-local-bundle-<version>
|
||||
```
|
||||
|
||||
Проверить `.env` и при необходимости изменить порты.
|
||||
|
||||
Импортировать images:
|
||||
|
||||
```bash
|
||||
./scripts/import-images.sh
|
||||
```
|
||||
|
||||
Создать базы данных:
|
||||
|
||||
```bash
|
||||
./scripts/init-db.sh
|
||||
```
|
||||
|
||||
Запустить приложение:
|
||||
|
||||
```bash
|
||||
./scripts/start.sh
|
||||
```
|
||||
|
||||
`start.sh` также запускает `init-db.sh`, если не задано `SKIP_DB_INIT=true`.
|
||||
|
||||
## Остановка и статус
|
||||
|
||||
```bash
|
||||
./scripts/status.sh
|
||||
./scripts/stop.sh
|
||||
```
|
||||
|
||||
Чтобы удалить volumes с данными Postgres/Kafka:
|
||||
|
||||
```bash
|
||||
./scripts/stop.sh -v
|
||||
```
|
||||
|
||||
## Открытые порты
|
||||
|
||||
- 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`
|
||||
- Request Service: `http://localhost:7005`
|
||||
- Slots Service: `http://localhost:7006`
|
||||
- UI: `http://localhost:7008`
|
||||
- Stations: `http://localhost:7009`
|
||||
- Mission Planning: `http://localhost:7010`
|
||||
- TGU: `http://localhost:7011`
|
||||
- Coverage Scheme: `http://localhost:7012`
|
||||
- Satellite Catalog: `http://localhost:7013`
|
||||
- Dynamic Plan: `http://localhost:7014`
|
||||
- Postgres: `localhost:5432`
|
||||
- Kafka external listener: `localhost:29092`
|
||||
|
||||
## Проверка готовности
|
||||
|
||||
Config Server:
|
||||
|
||||
```bash
|
||||
curl http://localhost:38888/actuator/health
|
||||
curl http://localhost:38888/pcp-ui-service/local,docker-local
|
||||
```
|
||||
|
||||
UI:
|
||||
|
||||
```bash
|
||||
curl http://localhost:7008/actuator/health
|
||||
```
|
||||
|
||||
Статус контейнеров:
|
||||
|
||||
```bash
|
||||
./scripts/status.sh
|
||||
```
|
||||
|
||||
## Config Server
|
||||
|
||||
В локальном сценарии `spring-cloud-config-server` запускается с:
|
||||
|
||||
```text
|
||||
SPRING_PROFILES_ACTIVE=local
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS=file:/config-repo
|
||||
```
|
||||
|
||||
`CONFIG_GIT_URI`, GitLab token и `git clone` не используются.
|
||||
|
||||
Сервисы запускаются с профилями:
|
||||
|
||||
```text
|
||||
SPRING_PROFILES_ACTIVE=local,docker-local
|
||||
SPRING_CLOUD_CONFIG_PROFILE=local,docker-local
|
||||
SPRING_CLOUD_CONFIG_LABEL=
|
||||
```
|
||||
|
||||
Профиль `local` сохраняет существующие service-specific настройки, а `docker-local` переопределяет IP-адреса на Docker Compose DNS names:
|
||||
|
||||
- `postgres`
|
||||
- `kafka`
|
||||
- `pcp-ballistics-service`
|
||||
- `slots-service`
|
||||
- остальные service names из `docker-compose.yml`
|
||||
|
||||
## Базы данных
|
||||
|
||||
`scripts/init-db.sh` создаёт только пустые базы данных:
|
||||
|
||||
- `pcp_ballistics`
|
||||
- `pcp_requests`
|
||||
- `pcp_missions`
|
||||
- `pcp_slots`
|
||||
- `pcp_complex_plan`
|
||||
- `pcp_satellite_catalog`
|
||||
- `pcp_stations`
|
||||
- `pcp_tgu`
|
||||
- `pcp_tle`
|
||||
- `pcp_satellites`
|
||||
|
||||
Таблицы, схемы и seed data вручную не создаются. Схемы создаются существующими Flyway migrations внутри сервисов при старте приложений.
|
||||
|
||||
`pcp_satellites` добавлена дополнительно, потому что текущий `config-repo/pcp-complex-mission-service.yaml` использует эту БД для `pcp-complex-mission-service`.
|
||||
Executable
+170
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
|
||||
version="${LOCAL_BUNDLE_VERSION:-${1:-}}"
|
||||
if [[ -z "$version" ]]; then
|
||||
if git -C "$repo_root" rev-parse --short HEAD >/dev/null 2>&1; then
|
||||
version="$(git -C "$repo_root" rev-parse --short HEAD)"
|
||||
else
|
||||
version="$(date +%Y%m%d%H%M%S)"
|
||||
fi
|
||||
fi
|
||||
|
||||
bundle_name="pcp-local-bundle-$version"
|
||||
build_dir="$script_dir/build"
|
||||
dist_dir="$build_dir/$bundle_name"
|
||||
docker_contexts_dir="$build_dir/docker-contexts"
|
||||
archive_path="$build_dir/$bundle_name.tar.gz"
|
||||
|
||||
service_names=(
|
||||
spring-cloud-config-server
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-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
|
||||
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}"
|
||||
include_infra_images="${INCLUDE_INFRA_IMAGES:-false}"
|
||||
|
||||
gradle_common_args=(
|
||||
"--no-parallel"
|
||||
"--max-workers=$gradle_max_workers"
|
||||
"-Dorg.gradle.jvmargs=$gradle_jvmargs"
|
||||
"-Pkotlin.daemon.jvmargs=$kotlin_daemon_jvmargs"
|
||||
)
|
||||
|
||||
infra_images=(
|
||||
"${POSTGRES_IMAGE:-postgis/postgis:16-3.4}"
|
||||
"${KAFKA_IMAGE:-apache/kafka:3.7.2}"
|
||||
)
|
||||
|
||||
sanitize_image_name() {
|
||||
printf '%s' "$1" | sed 's#[/:@]#-#g'
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
copy_config_repo() {
|
||||
local target_dir="$1"
|
||||
local source_file
|
||||
|
||||
mkdir -p "$target_dir"
|
||||
(
|
||||
cd "$repo_root/config-repo"
|
||||
find . -type f \
|
||||
! -path './build/*' \
|
||||
! -path './.gradle/*' \
|
||||
! -name '*.log' \
|
||||
! -name '*.tmp' \
|
||||
-print0
|
||||
) | while IFS= read -r -d '' source_file; do
|
||||
mkdir -p "$target_dir/$(dirname "$source_file")"
|
||||
cp "$repo_root/config-repo/$source_file" "$target_dir/$source_file"
|
||||
done
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
require_command docker
|
||||
require_command tar
|
||||
|
||||
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"
|
||||
for service_name in "${service_names[@]}"; do
|
||||
echo "Building bootJar for $service_name..."
|
||||
"$repo_root/gradlew" "${gradle_common_args[@]}" ":services:$service_name:bootJar"
|
||||
done
|
||||
|
||||
rm -rf "$dist_dir" "$docker_contexts_dir" "$archive_path"
|
||||
mkdir -p "$dist_dir/images" "$docker_contexts_dir"
|
||||
|
||||
echo "Building service Docker images..."
|
||||
service_images=()
|
||||
for service_name in "${service_names[@]}"; do
|
||||
image_name="pcp/$service_name:$version"
|
||||
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"
|
||||
service_images+=("$image_name")
|
||||
done
|
||||
|
||||
echo "Saving service Docker images into one archive..."
|
||||
docker save --output "$dist_dir/images/pcp-services.tar" "${service_images[@]}"
|
||||
|
||||
if [[ "$include_infra_images" == "true" ]]; then
|
||||
echo "Pulling and saving infrastructure images..."
|
||||
for image_name in "${infra_images[@]}"; do
|
||||
image_file="$(sanitize_image_name "$image_name").tar"
|
||||
docker pull "$image_name"
|
||||
docker save --output "$dist_dir/images/$image_file" "$image_name"
|
||||
done
|
||||
else
|
||||
echo "Skipping public infrastructure images. They will be pulled by docker compose on the target machine."
|
||||
printf '%s\n' "${infra_images[@]}" > "$dist_dir/images/public-images.txt"
|
||||
fi
|
||||
|
||||
echo "Preparing bundle files..."
|
||||
cp "$script_dir/docker-compose.yml" "$dist_dir/docker-compose.yml"
|
||||
cp "$script_dir/.env.example" "$dist_dir/.env.example"
|
||||
cp "$script_dir/.env.example" "$dist_dir/.env"
|
||||
sed -i "s/^PCP_IMAGE_TAG=.*/PCP_IMAGE_TAG=$version/" "$dist_dir/.env"
|
||||
cp "$script_dir/README-local.md" "$dist_dir/README-local.md"
|
||||
cp -R "$script_dir/scripts" "$dist_dir/scripts"
|
||||
copy_config_repo "$dist_dir/config-repo"
|
||||
|
||||
find "$dist_dir/scripts" -type f -name '*.sh' -exec chmod +x {} +
|
||||
|
||||
echo "Creating archive..."
|
||||
tar -C "$build_dir" -czf "$archive_path" "$bundle_name"
|
||||
|
||||
echo "Local bundle created: $archive_path"
|
||||
echo "Bundle version: $version"
|
||||
echo "To use: tar -xzf $archive_path && cd $bundle_name"
|
||||
@@ -0,0 +1,187 @@
|
||||
name: ${COMPOSE_PROJECT_NAME:-pcp-local}
|
||||
|
||||
x-pcp-service-env: &pcp-service-env
|
||||
CONFIG_SERVER_URI: http://spring-cloud-config-server:8888
|
||||
CONFIG_SERVER_FAIL_FAST: "true"
|
||||
SPRING_PROFILES_ACTIVE: local,docker-local
|
||||
SPRING_CLOUD_CONFIG_PROFILE: local,docker-local
|
||||
SPRING_CLOUD_CONFIG_LABEL: ""
|
||||
SPRING_KAFKA_ADMIN_AUTO_CREATE: "true"
|
||||
SPRING_KAFKA_LISTENER_AUTO_STARTUP: "true"
|
||||
|
||||
x-pcp-service-common: &pcp-service-common
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
spring-cloud-config-server:
|
||||
condition: service_started
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: ${POSTGRES_IMAGE:-postgis/postgis:16-3.4}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- "${POSTGRES_PORT:-5432}:5432"
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
|
||||
kafka:
|
||||
image: ${KAFKA_IMAGE:-apache/kafka:3.7.2}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
KAFKA_NODE_ID: "1"
|
||||
KAFKA_PROCESS_ROLES: broker,controller
|
||||
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
|
||||
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:29092
|
||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:${KAFKA_PORT:-29092}
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT
|
||||
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
||||
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
||||
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1"
|
||||
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1"
|
||||
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1"
|
||||
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0"
|
||||
KAFKA_LOG_DIRS: /var/lib/kafka/data
|
||||
ports:
|
||||
- "${KAFKA_PORT:-29092}:29092"
|
||||
volumes:
|
||||
- kafka-data:/var/lib/kafka/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server kafka:9092 --list >/dev/null 2>&1"]
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 30
|
||||
|
||||
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
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: local
|
||||
CONFIG_NATIVE_SEARCH_LOCATIONS: file:/config-repo
|
||||
SERVER_PORT: 8888
|
||||
ports:
|
||||
- "${CONFIG_SERVER_PORT:-38888}:8888"
|
||||
volumes:
|
||||
- ${CONFIG_REPO_DIR:-./config-repo}:/config-repo:ro
|
||||
|
||||
pcp-srpring-boot-admin-server:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-srpring-boot-admin-server:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
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}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_COMPLEX_MISSION_PORT:-7002}:7002"
|
||||
|
||||
pcp-ballistics-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-ballistics-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_BALLISTICS_PORT:-7003}:7003"
|
||||
|
||||
pcp-request-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-request-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_REQUEST_PORT:-7005}:7005"
|
||||
|
||||
slots-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/slots-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_SLOTS_PORT:-7006}:7006"
|
||||
|
||||
pcp-ui-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-ui-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_UI_PORT:-7008}:7008"
|
||||
|
||||
pcp-stations-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-stations-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_STATIONS_PORT:-7009}:7009"
|
||||
|
||||
pcp-mission-planing-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-mission-planing-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_MISSION_PORT:-7010}:7010"
|
||||
|
||||
pcp-tgu-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-tgu-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_TGU_PORT:-7011}:7011"
|
||||
|
||||
pcp-coverage-scheme-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-coverage-scheme-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_COVERAGE_SCHEME_PORT:-7012}:7012"
|
||||
|
||||
pcp-satellite-catalog-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-satellite-catalog-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_SATELLITE_CATALOG_PORT:-7013}:7013"
|
||||
|
||||
pcp-dynamic-plan-service:
|
||||
<<: *pcp-service-common
|
||||
image: pcp/pcp-dynamic-plan-service:${PCP_IMAGE_TAG:-local}
|
||||
environment:
|
||||
<<: *pcp-service-env
|
||||
ports:
|
||||
- "${PCP_DYNAMIC_PLAN_PORT:-7014}:7014"
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
kafka-data:
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
bundle_dir="$(cd "$script_dir/.." && pwd)"
|
||||
images_dir="$bundle_dir/images"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ ! -f "$bundle_dir/.env" && -f "$bundle_dir/.env.example" ]]; then
|
||||
cp "$bundle_dir/.env.example" "$bundle_dir/.env"
|
||||
echo "Created .env from .env.example"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_file
|
||||
|
||||
if [[ ! -d "$images_dir" ]]; then
|
||||
echo "Images directory not found: $images_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shopt -s nullglob
|
||||
image_archives=("$images_dir"/*.tar)
|
||||
if (( ${#image_archives[@]} == 0 )); then
|
||||
echo "No Docker image archives found in $images_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for image_archive in "${image_archives[@]}"; do
|
||||
echo "Loading image: $(basename "$image_archive")"
|
||||
docker load -i "$image_archive"
|
||||
done
|
||||
|
||||
if [[ -f "$images_dir/public-images.txt" ]]; then
|
||||
echo "Public images are not bundled and will be pulled by docker compose if missing:"
|
||||
sed 's/^/ - /' "$images_dir/public-images.txt"
|
||||
fi
|
||||
|
||||
cd "$bundle_dir"
|
||||
echo "Starting postgres, kafka and spring-cloud-config-server..."
|
||||
compose up -d postgres kafka spring-cloud-config-server
|
||||
|
||||
echo "Images imported and base services requested."
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
bundle_dir="$(cd "$script_dir/.." && pwd)"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ ! -f "$bundle_dir/.env" && -f "$bundle_dir/.env.example" ]]; then
|
||||
cp "$bundle_dir/.env.example" "$bundle_dir/.env"
|
||||
echo "Created .env from .env.example"
|
||||
fi
|
||||
}
|
||||
|
||||
load_env() {
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source "$bundle_dir/.env"
|
||||
set +a
|
||||
}
|
||||
|
||||
wait_for_postgres() {
|
||||
local attempt
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T postgres pg_isready -U "${POSTGRES_USER:-postgres}" -d postgres >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Postgres is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
create_database_if_missing() {
|
||||
local db_name="$1"
|
||||
local exists
|
||||
|
||||
exists="$(
|
||||
compose exec -T postgres 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"
|
||||
compose exec -T postgres createdb -U "${POSTGRES_USER:-postgres}" "$db_name"
|
||||
}
|
||||
|
||||
databases=(
|
||||
pcp_ballistics
|
||||
pcp_requests
|
||||
pcp_missions
|
||||
pcp_slots
|
||||
pcp_complex_plan
|
||||
pcp_satellite_catalog
|
||||
pcp_stations
|
||||
pcp_tgu
|
||||
pcp_tle
|
||||
pcp_satellites
|
||||
)
|
||||
|
||||
ensure_env_file
|
||||
load_env
|
||||
|
||||
cd "$bundle_dir"
|
||||
compose up -d postgres
|
||||
wait_for_postgres
|
||||
|
||||
for db_name in "${databases[@]}"; do
|
||||
create_database_if_missing "$db_name"
|
||||
done
|
||||
|
||||
echo "Database initialization completed. Tables are left to service Flyway migrations."
|
||||
echo "No schema objects or seed data were created by this script."
|
||||
Executable
+112
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
bundle_dir="$(cd "$script_dir/.." && pwd)"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
if [[ ! -f "$bundle_dir/.env" && -f "$bundle_dir/.env.example" ]]; then
|
||||
cp "$bundle_dir/.env.example" "$bundle_dir/.env"
|
||||
echo "Created .env from .env.example"
|
||||
fi
|
||||
}
|
||||
|
||||
load_env() {
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source "$bundle_dir/.env"
|
||||
set +a
|
||||
}
|
||||
|
||||
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_http() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local attempt
|
||||
|
||||
for attempt in {1..90}; do
|
||||
if http_get "$url"; then
|
||||
echo "$name is ready: $url"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "$name is not ready after 180 seconds: $url" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for_kafka() {
|
||||
local attempt
|
||||
for attempt in {1..60}; do
|
||||
if compose exec -T kafka kafka-topics.sh --bootstrap-server kafka:9092 --list >/dev/null 2>&1; then
|
||||
echo "Kafka is ready."
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Kafka is not ready after 120 seconds." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
app_services=(
|
||||
pcp-srpring-boot-admin-server
|
||||
pcp-satellite-catalog-service
|
||||
pcp-ballistics-service
|
||||
pcp-request-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
|
||||
tle-monitoring-service
|
||||
pcp-tgu-service
|
||||
)
|
||||
|
||||
ensure_env_file
|
||||
load_env
|
||||
|
||||
cd "$bundle_dir"
|
||||
|
||||
echo "Starting infrastructure..."
|
||||
compose up -d postgres kafka
|
||||
wait_for_kafka
|
||||
|
||||
if [[ "${SKIP_DB_INIT:-false}" != "true" ]]; then
|
||||
"$script_dir/init-db.sh"
|
||||
fi
|
||||
|
||||
echo "Starting spring-cloud-config-server..."
|
||||
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[@]}"
|
||||
|
||||
echo "Application startup requested."
|
||||
compose ps
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
bundle_dir="$(cd "$script_dir/.." && pwd)"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
cd "$bundle_dir"
|
||||
compose ps
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
bundle_dir="$(cd "$script_dir/.." && pwd)"
|
||||
|
||||
compose() {
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
docker compose "$@"
|
||||
elif command -v docker-compose >/dev/null 2>&1; then
|
||||
docker-compose "$@"
|
||||
else
|
||||
echo "docker compose or docker-compose is required." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
cd "$bundle_dir"
|
||||
compose down "$@"
|
||||
Reference in New Issue
Block a user