| @@ -200,8 +200,19 @@ function Prepare-Package { | |||||
| } | } | ||||
| New-Item -ItemType Directory -Force $PackageDir | Out-Null | New-Item -ItemType Directory -Force $PackageDir | Out-Null | ||||
| Copy-Item (Join-Path $ScriptDir "docker-compose.runtime.yml") (Join-Path $PackageDir "docker-compose.yml") -Force | |||||
| Copy-Item (Join-Path $ScriptDir ".env.example") (Join-Path $PackageDir ".env.example") -Force | |||||
| $ComposeSource = Join-Path $ScriptDir "docker-compose.runtime.yml" | |||||
| $EnvSource = Join-Path $ScriptDir ".env.example" | |||||
| $TestComposeSource = Join-Path $ScriptDir "test\docker-compose.yml" | |||||
| $TestEnvSource = Join-Path $ScriptDir "test\env.txt" | |||||
| if (Test-Path $TestComposeSource) { | |||||
| $ComposeSource = $TestComposeSource | |||||
| } | |||||
| if (Test-Path $TestEnvSource) { | |||||
| $EnvSource = $TestEnvSource | |||||
| } | |||||
| Copy-Item $ComposeSource (Join-Path $PackageDir "docker-compose.yml") -Force | |||||
| Copy-Item $EnvSource (Join-Path $PackageDir ".env.example") -Force | |||||
| Copy-Item (Join-Path $ScriptDir "install.sh") (Join-Path $PackageDir "install.sh") -Force | Copy-Item (Join-Path $ScriptDir "install.sh") (Join-Path $PackageDir "install.sh") -Force | ||||
| Copy-Item (Join-Path $ScriptDir "README.md") (Join-Path $PackageDir "README.md") -Force | Copy-Item (Join-Path $ScriptDir "README.md") (Join-Path $PackageDir "README.md") -Force | ||||
| } | } | ||||
| @@ -150,8 +150,17 @@ prepare_package() { | |||||
| rm -rf "$PACKAGE_DIR" | rm -rf "$PACKAGE_DIR" | ||||
| mkdir -p "$PACKAGE_DIR" | mkdir -p "$PACKAGE_DIR" | ||||
| cp "$SCRIPT_DIR/docker-compose.runtime.yml" "$PACKAGE_DIR/docker-compose.yml" | |||||
| cp "$SCRIPT_DIR/.env.example" "$PACKAGE_DIR/.env.example" | |||||
| local compose_src="$SCRIPT_DIR/docker-compose.runtime.yml" | |||||
| local env_src="$SCRIPT_DIR/.env.example" | |||||
| if [[ -f "$SCRIPT_DIR/test/docker-compose.yml" ]]; then | |||||
| compose_src="$SCRIPT_DIR/test/docker-compose.yml" | |||||
| fi | |||||
| if [[ -f "$SCRIPT_DIR/test/env.txt" ]]; then | |||||
| env_src="$SCRIPT_DIR/test/env.txt" | |||||
| fi | |||||
| cp "$compose_src" "$PACKAGE_DIR/docker-compose.yml" | |||||
| cp "$env_src" "$PACKAGE_DIR/.env.example" | |||||
| cp "$SCRIPT_DIR/install.sh" "$PACKAGE_DIR/install.sh" | cp "$SCRIPT_DIR/install.sh" "$PACKAGE_DIR/install.sh" | ||||
| cp "$SCRIPT_DIR/README.md" "$PACKAGE_DIR/README.md" | cp "$SCRIPT_DIR/README.md" "$PACKAGE_DIR/README.md" | ||||
| @@ -199,4 +208,3 @@ fi | |||||
| prepare_package | prepare_package | ||||
| save_images | save_images | ||||
| archive_package | archive_package | ||||
| @@ -0,0 +1,231 @@ | |||||
| x-app-env: &app-env | |||||
| env_file: | |||||
| - .env | |||||
| restart: unless-stopped | |||||
| networks: | |||||
| - emp-net | |||||
| x-java-depends: &java-depends | |||||
| nacos: | |||||
| condition: service_healthy | |||||
| mysql: | |||||
| condition: service_healthy | |||||
| redis: | |||||
| condition: service_healthy | |||||
| services: | |||||
| mysql: | |||||
| image: ${MYSQL_IMAGE:-mysql:8.0} | |||||
| restart: unless-stopped | |||||
| ports: | |||||
| - "0.0.0.0:${MYSQL_HOST_PORT:-23306}:3306" | |||||
| environment: | |||||
| TZ: Asia/Shanghai | |||||
| MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} | |||||
| MYSQL_DATABASE: ${MYSQL_DATABASE:-emp} | |||||
| command: | |||||
| - --character-set-server=utf8mb4 | |||||
| - --collation-server=utf8mb4_0900_ai_ci | |||||
| - --default-time-zone=+08:00 | |||||
| - --max-connections=1000 | |||||
| volumes: | |||||
| - mysql_data:/var/lib/mysql | |||||
| healthcheck: | |||||
| test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p\"$${MYSQL_ROOT_PASSWORD}\" --silent"] | |||||
| interval: 10s | |||||
| timeout: 5s | |||||
| retries: 30 | |||||
| networks: | |||||
| - emp-net | |||||
| redis: | |||||
| image: ${REDIS_IMAGE:-redis:7-alpine} | |||||
| restart: unless-stopped | |||||
| environment: | |||||
| REDIS_PASSWORD: ${REDIS_PASSWORD} | |||||
| command: ["sh", "-c", "redis-server --appendonly yes --requirepass \"$${REDIS_PASSWORD}\""] | |||||
| volumes: | |||||
| - redis_data:/data | |||||
| healthcheck: | |||||
| test: ["CMD-SHELL", "redis-cli -a \"$${REDIS_PASSWORD}\" ping | grep -q PONG"] | |||||
| interval: 10s | |||||
| timeout: 5s | |||||
| retries: 30 | |||||
| networks: | |||||
| - emp-net | |||||
| kafka: | |||||
| image: ${KAFKA_IMAGE:-bitnami/kafka:3.7.0} | |||||
| restart: unless-stopped | |||||
| ports: | |||||
| - "0.0.0.0:${KAFKA_HOST_PORT:-29362}:9094" | |||||
| environment: | |||||
| ALLOW_PLAINTEXT_LISTENER: "yes" | |||||
| KAFKA_CFG_NODE_ID: 1 | |||||
| KAFKA_CFG_PROCESS_ROLES: controller,broker | |||||
| KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093 | |||||
| KAFKA_CFG_LISTENERS: INTERNAL://:9092,CONTROLLER://:9093,EXTERNAL://:9094 | |||||
| KAFKA_CFG_ADVERTISED_LISTENERS: INTERNAL://kafka:9092,EXTERNAL://${PUBLIC_HOST}:${KAFKA_HOST_PORT:-29362} | |||||
| KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT | |||||
| KAFKA_CFG_INTER_BROKER_LISTENER_NAME: INTERNAL | |||||
| KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER | |||||
| KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "true" | |||||
| KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 | |||||
| KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1 | |||||
| KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR: 1 | |||||
| volumes: | |||||
| - kafka_data:/bitnami/kafka | |||||
| healthcheck: | |||||
| test: ["CMD-SHELL", "/opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --list >/dev/null 2>&1"] | |||||
| interval: 10s | |||||
| timeout: 5s | |||||
| retries: 30 | |||||
| networks: | |||||
| - emp-net | |||||
| kafka-init: | |||||
| image: ${KAFKA_IMAGE:-bitnami/kafka:3.7.0} | |||||
| restart: "no" | |||||
| depends_on: | |||||
| kafka: | |||||
| condition: service_healthy | |||||
| entrypoint: ["/bin/bash", "-ec"] | |||||
| environment: | |||||
| KAFKA_TOPIC: ${KAFKA_TOPIC:-vehicle-data} | |||||
| command: | | |||||
| echo "create kafka topic: $${KAFKA_TOPIC}" | |||||
| /opt/bitnami/kafka/bin/kafka-topics.sh \ | |||||
| --bootstrap-server kafka:9092 \ | |||||
| --create \ | |||||
| --if-not-exists \ | |||||
| --topic "$${KAFKA_TOPIC}" \ | |||||
| --partitions 3 \ | |||||
| --replication-factor 1 | |||||
| /opt/bitnami/kafka/bin/kafka-topics.sh \ | |||||
| --bootstrap-server kafka:9092 \ | |||||
| --describe \ | |||||
| --topic "$${KAFKA_TOPIC}" | |||||
| networks: | |||||
| - emp-net | |||||
| tdengine: | |||||
| image: ${TDENGINE_IMAGE:-tdengine/tdengine:3.3.6.0} | |||||
| hostname: tdengine | |||||
| privileged: true | |||||
| restart: unless-stopped | |||||
| ports: | |||||
| - "0.0.0.0:${TDENGINE_REST_HOST_PORT:-37363}:6041" | |||||
| environment: | |||||
| TZ: Asia/Shanghai | |||||
| TAOS_FQDN: tdengine | |||||
| TDENGINE_DATABASE: ${TDENGINE_DATABASE:-emp} | |||||
| volumes: | |||||
| - tdengine_data:/var/lib/taos | |||||
| - tdengine_log:/var/log/taos | |||||
| healthcheck: | |||||
| test: ["CMD-SHELL", "taos -s \"create database if not exists $${TDENGINE_DATABASE}; show databases;\" >/dev/null 2>&1"] | |||||
| interval: 10s | |||||
| timeout: 5s | |||||
| retries: 30 | |||||
| networks: | |||||
| - emp-net | |||||
| nacos: | |||||
| image: ${NACOS_IMAGE:-nacos/nacos-server:v2.3.2-slim} | |||||
| restart: unless-stopped | |||||
| environment: | |||||
| MODE: standalone | |||||
| JVM_XMS: 256m | |||||
| JVM_XMX: 512m | |||||
| SPRING_DATASOURCE_PLATFORM: "" | |||||
| NACOS_AUTH_ENABLE: ${NACOS_AUTH_ENABLE:-true} | |||||
| NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY:-emp} | |||||
| NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE:-emp2026} | |||||
| NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN} | |||||
| volumes: | |||||
| - nacos_data:/home/nacos/data | |||||
| - nacos_logs:/home/nacos/logs | |||||
| healthcheck: | |||||
| test: ["CMD-SHELL", "curl -sf http://127.0.0.1:8848/nacos/actuator/health || exit 1"] | |||||
| interval: 10s | |||||
| timeout: 5s | |||||
| retries: 30 | |||||
| networks: | |||||
| - emp-net | |||||
| emp-gateway: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-gateway:${IMAGE_TAG:-latest} | |||||
| depends_on: | |||||
| <<: *java-depends | |||||
| emp-auth: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-auth:${IMAGE_TAG:-latest} | |||||
| depends_on: | |||||
| <<: *java-depends | |||||
| emp-monitor: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-monitor:${IMAGE_TAG:-latest} | |||||
| depends_on: | |||||
| <<: *java-depends | |||||
| tdengine: | |||||
| condition: service_healthy | |||||
| emp-pdf: | |||||
| condition: service_started | |||||
| emp-data: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-data:${IMAGE_TAG:-latest} | |||||
| depends_on: | |||||
| <<: *java-depends | |||||
| tdengine: | |||||
| condition: service_healthy | |||||
| kafka-init: | |||||
| condition: service_completed_successfully | |||||
| emp-ws: | |||||
| condition: service_started | |||||
| emp-pdf: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-pdf:${IMAGE_TAG:-latest} | |||||
| emp-ws: | |||||
| <<: *app-env | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-ws:${IMAGE_TAG:-latest} | |||||
| ports: | |||||
| - "0.0.0.0:${WS_HOST_PORT:-37362}:3000" | |||||
| depends_on: | |||||
| mysql: | |||||
| condition: service_healthy | |||||
| redis: | |||||
| condition: service_healthy | |||||
| kafka-init: | |||||
| condition: service_completed_successfully | |||||
| emp-admin: | |||||
| image: ${IMAGE_NAMESPACE:-emp-test}/emp-admin:${IMAGE_TAG:-latest} | |||||
| restart: unless-stopped | |||||
| ports: | |||||
| - "0.0.0.0:${ADMIN_HOST_PORT:-37361}:80" | |||||
| depends_on: | |||||
| emp-gateway: | |||||
| condition: service_started | |||||
| emp-ws: | |||||
| condition: service_started | |||||
| networks: | |||||
| - emp-net | |||||
| networks: | |||||
| emp-net: | |||||
| driver: bridge | |||||
| volumes: | |||||
| mysql_data: | |||||
| redis_data: | |||||
| kafka_data: | |||||
| tdengine_data: | |||||
| tdengine_log: | |||||
| nacos_data: | |||||
| nacos_logs: | |||||
| @@ -0,0 +1,154 @@ | |||||
| # EMP 隔离测试环境变量模板 | |||||
| # 使用方式:复制为 .env 后按目标服务器实际情况修改。 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 镜像与项目名称 | |||||
| # ----------------------------------------------------------------------------- | |||||
| COMPOSE_PROJECT_NAME=emp-test | |||||
| CONTAINER_PREFIX=emp-test | |||||
| IMAGE_NAMESPACE=emp-test | |||||
| IMAGE_TAG=latest | |||||
| # 服务器外网 IP 或域名。 | |||||
| # Kafka 对外访问会把这个地址写入 advertised.listeners,外部客户端必须能访问它。 | |||||
| PUBLIC_HOST=1.14.103.234 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 对外端口 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 前端访问:http://PUBLIC_HOST:ADMIN_HOST_PORT | |||||
| ADMIN_HOST_PORT=37361 | |||||
| GATEWAY_HOST_PORT=9000 | |||||
| WS_HOST_PORT=37362 | |||||
| PDF_HOST_PORT=3100 | |||||
| NACOS_HOST_PORT=9008 | |||||
| NACOS_GRPC_HOST_PORT=10008 | |||||
| # MySQL / Kafka / TDengine 需要开放到宿主机,便于 Navicat、Kafka 客户端、TDengine Web/REST 调试。 | |||||
| # 如果宿主机端口已被其他项目占用,改这里即可。 | |||||
| MYSQL_HOST_PORT=23306 | |||||
| KAFKA_HOST_PORT=29362 | |||||
| TDENGINE_HOST_PORT=6030 | |||||
| TDENGINE_REST_HOST_PORT=37363 | |||||
| TDENGINE_RPC_HOST_PORT=6043 | |||||
| TDENGINE_RPC_UDP_HOST_PORT=6044 | |||||
| TDENGINE_KEEPER_HOST_PORT=6060 | |||||
| # Redis 默认只绑定本机,避免直接暴露公网;确实需要外部访问再改成 0.0.0.0。 | |||||
| REDIS_BIND_HOST=127.0.0.1 | |||||
| REDIS_HOST_PORT=16379 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 中间件镜像 | |||||
| # ----------------------------------------------------------------------------- | |||||
| MYSQL_IMAGE=mysql:8.0 | |||||
| REDIS_IMAGE=redis:7-alpine | |||||
| KAFKA_IMAGE=bitnami/kafka:3.7.0 | |||||
| TDENGINE_IMAGE=tdengine/tdengine:3.3.6.0 | |||||
| NACOS_IMAGE=nacos/nacos-server:v2.3.2-slim | |||||
| # ----------------------------------------------------------------------------- | |||||
| # MySQL 8.0 | |||||
| # ----------------------------------------------------------------------------- | |||||
| MYSQL_DATABASE=emp | |||||
| MYSQL_ROOT_PASSWORD=emp_2026_06_01_pwd | |||||
| DB_URL=jdbc:mysql://mysql:3306/emp?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai | |||||
| DB_USER=root | |||||
| DB_PWD=emp_2026_06_01_pwd | |||||
| # 给 emp_ws 模拟器读取车辆档案使用。 | |||||
| SIMULATOR_DB_HOST=mysql | |||||
| SIMULATOR_DB_PORT=3306 | |||||
| SIMULATOR_DB_USER=root | |||||
| SIMULATOR_DB_PASSWORD=emp_2026_06_01_pwd | |||||
| SIMULATOR_DB_DATABASE=emp | |||||
| SIMULATOR_DB_LIMIT=0 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # Redis | |||||
| # ----------------------------------------------------------------------------- | |||||
| REDIS_HOST=redis | |||||
| REDIS_PORT=6379 | |||||
| REDIS_PASSWORD=change-me-redis | |||||
| REDIS_DB=0 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # Kafka | |||||
| # ----------------------------------------------------------------------------- | |||||
| KAFKA_BROKERS=kafka:9092 | |||||
| KAFKA_GROUP_ID=ecmp-data-group-v2 | |||||
| KAFKA_TOPIC=Yuanjing-vehicle-mock-data | |||||
| KAFKA_USER= | |||||
| KAFKA_PWD= | |||||
| SIMULATOR_KAFKA_BROKERS=kafka:9092 | |||||
| SIMULATOR_KAFKA_TOPIC=Yuanjing-vehicle-mock-data | |||||
| SIMULATOR_KAFKA_USER= | |||||
| SIMULATOR_KAFKA_PASSWORD= | |||||
| SIMULATOR_KAFKA_CLIENT_ID=emp-simulator | |||||
| SIMULATOR_KAFKA_BATCH_SIZE=500 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # TDengine | |||||
| # ----------------------------------------------------------------------------- | |||||
| TDENGINE_DATABASE=emp | |||||
| TDENGINE_USER=root | |||||
| TDENGINE_PWD=taosdata | |||||
| TDENGINE_URL=jdbc:TAOS-RS://tdengine:6041/emp | |||||
| # ----------------------------------------------------------------------------- | |||||
| # Nacos | |||||
| # ----------------------------------------------------------------------------- | |||||
| NACOS_ADDR=nacos:8848 | |||||
| NACOS_USER=nacos | |||||
| NACOS_PWD=nacos | |||||
| NACOS_AUTH_ENABLE=true | |||||
| NACOS_AUTH_IDENTITY_KEY=emp | |||||
| NACOS_AUTH_IDENTITY_VALUE=emp2026 | |||||
| NACOS_AUTH_TOKEN=ZW1wLXBsYXRmb3JtLW5hY29zLXNlY3JldC1rZXktMjAyNg== | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 后端通用配置 | |||||
| # ----------------------------------------------------------------------------- | |||||
| SPRING_PROFILES_ACTIVE=prod | |||||
| JWT_SECRET=emp-platform-secret-key-2026-yjfs | |||||
| JWT_EXPIRATION=86400000 | |||||
| SCHEDULER_ENABLED=true | |||||
| # ----------------------------------------------------------------------------- | |||||
| # WebSocket / 模拟器 | |||||
| # ----------------------------------------------------------------------------- | |||||
| EMP_WS_ENV=production | |||||
| NODE_ENV=production | |||||
| PORT=3000 | |||||
| WS_INSTANCES=1 | |||||
| WS_HOST=emp-ws | |||||
| SERVER_API_BASE_URL=http://emp-gateway:9000/api | |||||
| SIMULATOR_ADMIN_USERNAME=admin | |||||
| SIMULATOR_LOGIN_AUTH=88871fe697e860463cd062cf3705b16f | |||||
| SIMULATOR_JWT_SECRET=emp-platform-secret-key-2026-yjfs | |||||
| # ----------------------------------------------------------------------------- | |||||
| # PDF 与前端地址 | |||||
| # ----------------------------------------------------------------------------- | |||||
| PDF_SERVICE_URL=http://emp-pdf:3100 | |||||
| PDF_FRONTEND_BASE_URL=http://1.14.103.234:37361 | |||||
| # ----------------------------------------------------------------------------- | |||||
| # 第三方配置,按需填写 | |||||
| # ----------------------------------------------------------------------------- | |||||
| AMAP_KEY= | |||||
| COS_SECRET_ID=AKIDynPmvra6PTIsypSr24uXxFKDtPipkUI0 | |||||
| COS_SECRET_KEY=Zv76sSq21oPq45vY0GJCuQjrnY6II3aF | |||||
| COS_REGION=ap-chengdu | |||||
| COS_BUCKET=emp-1258090764 | |||||
| SYNC_BASE_URL=https://example.com | |||||
| SYNC_TK=change-me | |||||
| SYNC_TENANT_ID=2047616403946835969 | |||||
| SYNC_REPORT_CRON=0 30 2 * * ? | |||||
| SYNC_REPORT_SYNC_ENABLED=false | |||||
| SYNC_REPORT_SYNC_CONCURRENCY=3 | |||||
| SYNC_REPORT_SYNC_GROUP_NAMES= | |||||
| SYNC_REPORT_CACHE_MISS_FETCH_ENABLED=false | |||||
| GROUP_REPORT_CRON=0 30 4 ? * THU,SUN | |||||