From 6c0f7d821ca0a25c3f0665ef25acc3d832120c4e Mon Sep 17 00:00:00 2001 From: Jiang Date: Wed, 21 Jan 2026 17:20:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9infra=E5=86=85=E5=AE=B9?= =?UTF-8?q?=EF=BC=9B=E7=A7=BB=E5=8A=A8project=5Finfo=E5=88=B0config?= =?UTF-8?q?=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/algorithms/online_Analysis.py | 2 +- app/infra/db/influxdb/api.py | 2 +- app/main.py | 2 +- app/services/simulation.py | 2 +- {app/services => configs}/project_info.py | 0 infra/docker/Dockerfile | 2 +- infra/docker/docker-compose.yml | 153 +++++++++++++++++++- requirements.txt | Bin 4554 -> 3168 bytes resources/old_requirements.txt | Bin 0 -> 4554 bytes resources/requirements2.txt | 168 ---------------------- 10 files changed, 152 insertions(+), 179 deletions(-) rename {app/services => configs}/project_info.py (100%) create mode 100644 resources/old_requirements.txt delete mode 100644 resources/requirements2.txt diff --git a/app/algorithms/online_Analysis.py b/app/algorithms/online_Analysis.py index c9fc28d..509bd11 100644 --- a/app/algorithms/online_Analysis.py +++ b/app/algorithms/online_Analysis.py @@ -18,7 +18,7 @@ import geopandas as gpd from sqlalchemy import create_engine import ast import sensitivity -import app.services.project_info as project_info +import configs.project_info as project_info import app.algorithms.api_ex.kmeans_sensor import app.algorithms.api_ex.Fdataclean import app.algorithms.api_ex.Pdataclean diff --git a/app/infra/db/influxdb/api.py b/app/infra/db/influxdb/api.py index 71c7325..4647740 100644 --- a/app/infra/db/influxdb/api.py +++ b/app/infra/db/influxdb/api.py @@ -27,7 +27,7 @@ import pandas as pd import openpyxl import pytz import app.infra.db.influxdb.info as influxdb_info -import app.services.project_info as project_info +import configs.project_info as project_info import app.services.time_api as time_api from app.native.api.postgresql_info import get_pgconn_string diff --git a/app/main.py b/app/main.py index 5be0bbd..2ad347c 100644 --- a/app/main.py +++ b/app/main.py @@ -47,7 +47,7 @@ import py_linq import app.services.time_api as time_api import app.services.simulation as simulation import app.services.globals as globals -import app.services.project_info as project_info +import configs.project_info as project_info from app.infra.db.timescaledb.database import db as tsdb from app.infra.db.postgresql.database import db as pgdb from app.algorithms.online_Analysis import * diff --git a/app/services/simulation.py b/app/services/simulation.py index af085f9..31984a8 100644 --- a/app/services/simulation.py +++ b/app/services/simulation.py @@ -19,7 +19,7 @@ import psycopg import logging import app.services.globals as globals import uuid -import app.services.project_info as project_info +import configs.project_info as project_info from app.native.api.postgresql_info import get_pgconn_string from timescaledb.internal_queries import InternalQueries as TimescaleInternalQueries from timescaledb.internal_queries import InternalStorage as TimescaleInternalStorage diff --git a/app/services/project_info.py b/configs/project_info.py similarity index 100% rename from app/services/project_info.py rename to configs/project_info.py diff --git a/infra/docker/Dockerfile b/infra/docker/Dockerfile index 6801213..3c0baa3 100644 --- a/infra/docker/Dockerfile +++ b/infra/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10-slim +FROM python:3.12-slim WORKDIR /app diff --git a/infra/docker/docker-compose.yml b/infra/docker/docker-compose.yml index 3f54ba1..a525af6 100644 --- a/infra/docker/docker-compose.yml +++ b/infra/docker/docker-compose.yml @@ -1,23 +1,164 @@ -version: '3.8' - services: + # ========================================== + # Core API Service + # ========================================== api: build: context: ../.. dockerfile: infra/docker/Dockerfile + container_name: tjwater_api + restart: always ports: - - "8000:8000" + - "${API_PORT}:8000" volumes: - ../../app:/app/app - ../../resources:/app/resources environment: - PYTHONPATH=/app + - REDIS_HOST=redis + - REDIS_PORT=${REDIS_PORT} + - REDIS_PASSWORD=${REDIS_PASSWORD} + # Add other DB connections here as needed by your app depends_on: - redis + - timescaledb + - postgis + # ========================================== + # Infrastructure Services + # ========================================== + + # --- Redis --- redis: - image: redis:alpine + image: redis:latest + container_name: redis + restart: always + command: redis-server --requirepass ${REDIS_PASSWORD} ports: - - "6379:6379" + - "${REDIS_PORT}:6379" + volumes: + - ./redis/data:/data -# Add other services as needed (postgres, influxdb, timescaledb) + # --- InfluxDB --- + influxdb: + image: influxdb:2.7 + container_name: influxdb + restart: always + environment: + DOCKER_INFLUXDB_INIT_MODE: setup + DOCKER_INFLUXDB_INIT_USERNAME: ${INFLUXDB_USER} + DOCKER_INFLUXDB_INIT_PASSWORD: ${INFLUXDB_PASSWORD} + DOCKER_INFLUXDB_INIT_ORG: ${INFLUXDB_ORG} + DOCKER_INFLUXDB_INIT_BUCKET: ${INFLUXDB_BUCKET} + DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: ${INFLUXDB_ADMIN_TOKEN} + ports: + - "${INFLUXDB_PORT}:8086" + volumes: + - ./influxdb/data:/var/lib/influxdb2 + + # --- Keycloak --- + keycloakDB: + image: postgis/postgis:14-3.5 + container_name: keycloakDB + restart: always + environment: + POSTGRES_DB: ${KEYCLOAK_DB_NAME} + POSTGRES_USER: ${KEYCLOAK_DB_USER} + POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD} + ports: + - "${KEYCLOAK_DB_PORT}:5432" + volumes: + - ./keycloak/db_data:/var/lib/postgresql/data + + keycloak: + image: keycloak/keycloak:latest + container_name: keycloak + restart: always + environment: + KC_HOSTNAME: localhost + KC_HOSTNAME_STRICT_BACKCHANNEL: "true" + KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USER} + KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD} + KC_HEALTH_ENABLED: "true" + KC_LOG_LEVEL: info + KC_DB: postgres + KC_DB_URL: jdbc:postgresql://keycloakDB:5432/${KEYCLOAK_DB_NAME} + KC_DB_USERNAME: ${KEYCLOAK_DB_USER} + KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD} + volumes: + - ./keycloak/themes:/opt/keycloak/themes + - ./keycloak/import:/opt/keycloak/data/import + healthcheck: + test: [ "CMD", "curl", "-f", "http://localhost:8080/health/ready" ] + interval: 15s + timeout: 2s + retries: 15 + command: [ "start-dev", "--import-realm" ] + ports: + - "${KEYCLOAK_PORT}:8080" + depends_on: + - keycloakDB + + # --- TimescaleDB & Grafana --- + timescaledb: + image: timescale/timescaledb:latest-pg15 + container_name: timescaledb + restart: always + environment: + POSTGRES_DB: ${TIMESCALE_DB_NAME} + POSTGRES_USER: ${TIMESCALE_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD_SHARED} + ports: + - "${TIMESCALE_PORT}:5432" + volumes: + - ./timescaledb/data:/var/lib/postgresql/data + + grafana: + image: grafana/grafana:latest + container_name: grafana + restart: always + ports: + - "${GRAFANA_PORT}:3000" + depends_on: + - timescaledb + volumes: + - ./timescaledb/grafana_data:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} + + # --- MapService (PostGIS & GeoServer) --- + postgis: + image: postgis/postgis:14-3.5 + container_name: postgis + restart: always + environment: + POSTGRES_DB: ${POSTGIS_DB_NAME} + POSTGRES_USER: ${POSTGIS_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD_SHARED} + ports: + - "${POSTGIS_PORT}:5432" + volumes: + - ./mapservice/data:/var/lib/postgresql/data + + geoserver: + image: docker.osgeo.org/geoserver:2.27.1 + container_name: geoserver + restart: always + ports: + - "${GEOSERVER_PORT}:8080" + depends_on: + - postgis + environment: + - GEOSERVER_ADMIN_USER=${GEOSERVER_ADMIN_USER} + - GEOSERVER_ADMIN_PASSWORD=${GEOSERVER_ADMIN_PASSWORD} + - INSTALL_EXTENSIONS=true + - STABLE_EXTENSIONS=css,vectortiles + - CORS_ENABLED=true + - CORS_ALLOWED_ORIGINS=* + volumes: + - ./mapservice/geoserver_data:/opt/geoserver_data + +networks: + default: + driver: bridge diff --git a/requirements.txt b/requirements.txt index 5b04d859b7842510b325e2b3b630f0ad3bd90c2a..0700705d639735fc3e37681d0a4e6107b02260bc 100644 GIT binary patch literal 3168 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